项目启动时,创建代理过程
initializeBean.applyBeanPostProcessorsAfterInitialization

由AnnotationAwareAspectJAutoProxyCreator来处理

AnnotationAwareAspectJAutoProxyCreator

wrapIfNecessary

- 通过getAdvicesAndAdvisorsForBean获取bean满足的Advisor,这里只有返回了事务相关的Advisor

- this.advisedBeans.put(cacheKey, Boolean.TRUE);放入缓存
- 开始创建代理createProxy
createProxy
创建动态代理,通过jdk或者cglib,这个在前面spring的分析由讲到,略

生成的cglib文件,下面是我们要测试的dynamicUpdate方法
执行MethodInterceptor的intercept方法,这里的MethodInterceptor是CglibAopProxy.DynamicAdvisedInterceptor

4. this.proxyTypes.put(cacheKey, proxy.getClass());缓存bean->代理Class
执行时,AOP处理
CglibAopProxy.DynamicAdvisedInterceptor执行intercept
这是通用的AOP执行过程
General purpose AOP callback. Used when the target is dynamic or when the proxy is not frozen.



最后执行MethodInterceptor的invoke回调。这里由TransactionInterceptor实现

TransactionInterceptor事务拦截器
invokeWithinTransaction

- 341行,获取注解上参数

- 342行,获取事务控制器TM。默认为JdbcTransactionManager

- 382行,创建事务对象

createTransactionIfNecessary创建TransactionInfo对象
status = tm.getTransaction(txAttr); 获取事务状态

doGetTransaction 获取事务对象

ConnectionHolder conHolder =(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());

- 通过obtainDataSource()获取dataSource
这里的dataSource是DynamicDataSource,这是我自定义的Datasource,用来做读写分离的
public class DynamicDataSource extends AbstractRoutingDataSource {
private Object writeDataSource;
private Object readDataSource;
@Override
public void afterPropertiesSet() {
if (this.writeDataSource == null) {
throw new IllegalArgumentException("Property 'writeDataSource' is required");
}
setDefaultTargetDataSource(writeDataSource);
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DynamicDataSourceGlobalEnum.WRITE.name(), writeDataSource);
if (readDataSource != null) {
targetDataSources.put(DynamicDataSourceGlobalEnum.READ.name(), readDataSource);
}
setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey() {
// 开启事务,用主数据源
return DynamicDataSourceHolder.getDataSource() == DynamicDataSourceGlobalEnum.WRITE ? DynamicDataSourceGlobalEnum.WRITE.name() : DynamicDataSourceGlobalEnum.READ.name();
}
}

2. TransactionSynchronizationManager.getResource

3. 返回事务对象

isExistingTransaction判断当前是否存在事务

startTransaction开启事务

doBegin
1. 获取数据库连接

2. 将数据库连接封装成ConnectionHolder,并设置到事务对象的connectionHolder字段中,最后返回连接对象

3. 设置只读事务标识

4. 查询数据库当前连接是否为自动提交,如果是自动提交设置为手动

5. 如果为只读事务


Statement执行executeUpdate(“SET TRANSACTION READ ONLY”);
6. 设置事务超时时间,默认为不超时(-1)

7. 绑定ConnectionHolder到当前线程


prepareSynchronization 初始化当前线程事务参数

所有属性都绑定到当前线程

prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);

把TransactionInfo绑定到当前线程


invocation.proceedWithInvocation(); 执行业务代码


cleanupTransactionInfo(txInfo);
在业务代码执行完成后,在finally中



commitTransactionAfterReturning 提交事务




最终调用Connection.commit提交事务

processReturnType(proxy, target, method, retVal);
执行通用AOP后置通知












![[架构之路-176]-《软考-系统分析师》-1-嵌入式系统分析与设计 - 实时性(任务切换时间、中断延迟时间、中断响应时间)、可靠性、功耗、体积、成本](https://img-blog.csdnimg.cn/4273303146bb413ea9ef10879cd6ede1.png)





