若要开启Spring的事务功能,可以使用Annotation注解的方式开启,@EnableTransactionManagement(proxyTargetClass = false),
这个注解会自动导入TransactionManagementConfigurationSelector类
然后TransactionManagementConfigurationSelector会去
通过查看父类,可知会在TransactionManagementConfiguration中调用
在调用invokeBeanFactoryPostProcessors方法时,会调用到PostProcessorRegistrationDelegate类的postProcessBeanDefinitionRegistry方法,PostProcessBeanDefinitionRegistry是在bean没有实例化之前调用的,bean所有的crud都会在这个类里边进行,还支持了一些注解,比如@Import,@ImportSource,@Aspect,@Configuration,@Conpononescan注解,都是在这类做的。
现在快速定位Import标签
在这里解析@Import,首先查收有没有继承与ImportSelector.class的类,
然后拿到连个数组类
也就是就刚刚那连个类
然后调用procesImports递归。
把数组的两个类变成bdf对象,具体是在loadBeanDefinition调用的
遍历这个类的支撑。
AutoProxyRegistrar.class主要做啥?
答案:aop的入口
这个主要是做什么呢
他主要的作用是创建切面对应advice,创建切面对应的pointcut,创建事务的属性类。
调用transactionAttributeSource函数最终会调用到AnnotationTransactionAttributeSource类,这个类主要目的是拿到,并负责解析Transactional注解的属性
注册advice
一般xxxxInterceptor类都会继承MethodInterceptor接口,意味着它会全局拦截。
Aop调用过程中,都会调用MethodInterceptor的实例。为什么所有的advice对象都要包装为MethodInterceptor类型的对象,因为不这么做的话,就会要写大量的ifelse,去判断每一个adivce的类型。
而且TransactionInterceptor肯定会在这个链式调用里边。
这里会将事务管理器注册进去
那么事务关系是做什么用的呢?事务管理器持有了连接池的引用,管理所有的连接。
观察这个事务管理器怎么来?
自己写一个方法,然后把对应的DataSource塞进去。
然后这个地方就会有值了
也可以在某个类上这么写。
在这个方法里边,会创建一个匿名类
匿名类中有一个这样的方法
匿名类的方法,就会调动的外层的proccess
拿到属性管理器,用来解析@Transaction注解的东西
获取方法上有@Transation注解的属性
解析@Transction注解
封装事务的n个属性,例如事务个例级别,是否只读,异常等。拿注解的属性如图
同一个代理对象,调用了两个不同的方法。如果调用两次如何拿去Connection?
第一次调用返回null
map是建立连接池对象和连接对象的映射,而resource明显是和当前线程绑定。
如果map不为空,就能拿到一个连接
断点第一次进来conHolder为空
第二次进来conHolder不为空
第一次进来ConnectionHolder为空所以不会走进来
然后会走到这里
创建事务的一些信息,并封装事务的一些状态,然后开启事务,然后改变事务的状态
在这里把当前事务放入的threadLocal中
Resource是ThreadLocal,把map塞入ThreadLocal里边,然后对map赋值,然后建立连接池和连接的对象,map记录的是当前用户线程和map的映射关系。也就是说通过当前用户线程,就可以拿到一个唯一的连接。
总结dobegin做了啥?
从连接池拿到连接,然后封窗成ConnectionHolder,然后把ConnectionHolder放入事务对象,设置个例界别,把自动提交关闭。