seata数据源代理流程
1-SeataDataSourceAutoConfiguration
创建SeataAutoDataSourceProxyCreator对象,默认seata模式为AT
2-SeataAutoDataSourceProxyCreator
- 设置advisor用于来接实现DataSource接口的实现类
public SeataAutoDataSourceProxyCreator(boolean useJdkProxy, String[] excludes, String dataSourceProxyMode) { setProxyTargetClass(!useJdkProxy); this.excludes = new HashSet<>(Arrays.asList(excludes)); // AT this.dataSourceProxyMode = dataSourceProxyMode; this.advisors = buildAdvisors(dataSourceProxyMode); } private Object[] buildAdvisors(String dataSourceProxyMode) { Advice advice = new SeataAutoDataSourceProxyAdvice(dataSourceProxyMode); return new Object[]{new DefaultIntroductionAdvisor(advice)}; }
- 重写wrapIfNecessary,设置数据源代理
@Override protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { // we only care DataSource bean if (!(bean instanceof DataSource)) { return bean; } // when this bean is just a simple DataSource, not SeataDataSourceProxy LOGGER.error("bean={}", bean.getClass().getSimpleName()); if (!(bean instanceof SeataDataSourceProxy)) { Object enhancer = super.wrapIfNecessary(bean, beanName, cacheKey); // this mean this bean is either excluded by user or had been proxy before if (bean == enhancer) { return bean; } // else, build proxy, put <origin, proxy> to holder and return enhancer DataSource origin = (DataSource) bean; SeataDataSourceProxy proxy = buildProxy(origin, dataSourceProxyMode); DataSourceProxyHolder.put(origin, proxy); LOGGER.error("bean2origin={}, proxy={}, proxy.targetDataSource={}", origin.getClass().getSimpleName(), proxy.getClass().getSimpleName(), proxy.getTargetDataSource()); return enhancer; } /* * things get dangerous when you try to register SeataDataSourceProxy bean by yourself! * if you insist on doing so, you must make sure your method return type is DataSource, * because this processor will never return any subclass of SeataDataSourceProxy */ LOGGER.warn("Manually register SeataDataSourceProxy(or its subclass) bean is discouraged! bean name: {}", beanName); SeataDataSourceProxy proxy = (SeataDataSourceProxy) bean; DataSource origin = proxy.getTargetDataSource(); LOGGER.error("TargetDataSource={}", origin.getClass().getSimpleName()); Object originEnhancer = super.wrapIfNecessary(origin, beanName, cacheKey); // this mean origin is either excluded by user or had been proxy before if (origin == originEnhancer) { return origin; } // else, put <origin, proxy> to holder and return originEnhancer DataSourceProxyHolder.put(origin, proxy); return originEnhancer; }
3-SeataAutoDataSourceProxyAdvice
所有实现DataSource接口的实现类都会再次被拦截,调用invoke方法
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
// check whether current context is expected
if (!inExpectedContext()) {
return invocation.proceed();
}
Method method = invocation.getMethod();
String name = method.getName();
Class<?>[] parameterTypes = method.getParameterTypes();
Method declared;
try {
declared = DataSource.class.getDeclaredMethod(name, parameterTypes);
} catch (NoSuchMethodException e) {
// mean this method is not declared by DataSource
return invocation.proceed();
}
// switch invoke instance to its proxy
DataSource origin = (DataSource) invocation.getThis();
SeataDataSourceProxy proxy = DataSourceProxyHolder.get(origin);
Object[] args = invocation.getArguments();
LOGGER.error("执行类={},执行方法={},方法参数={}", proxy.getClass().getSimpleName(), declared.getName(), args);
return declared.invoke(proxy, args);
}
标签:origin,return,seata,数据源,Object,代理,bean,proxy,DataSource
From: https://www.cnblogs.com/demon001/p/17174672.html