《Spring源码深度解析》十(1)
第十章:事务
10.1 切入点(自定义标签):
TxNamespaceHandler#init:
public void init() {
...
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
...
}
AnnotationDrivenBeanDefinitionParser#parse:
public BeanDefinition parse(Element element, ParserContext parserContext) {
...
String mode = element.getAttribute("mode");
if ("aspectj".equals(mode)) {
// mode="aspectj",即使用AspectJ的方式进行事务切入
registerTransactionAspect(element, parserContext);
...
}
else {
// mode="proxy"
AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
}
10.2 注册InfrastructureAdvisorAutoProxyCreator
10.1的parse中的AopAutoProxyConfigurer#configureAutoProxyCreator:
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
RootBeanDefinition sourceDef = new RootBeanDefinition(
"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
}
解析:
注册了InfrastructureAdvisorAutoPorxyCreator类型的bean
目的:此类间接实现了postProcessAfterInitialization方法,此方法对指定bean进行封装,即使用者实例化bean的时候会调用此方法
postProcessAfterInitialization的流程为:
1.找出指定bean对应的增强器。
找出增强器又分为两步,分成了获取所有增强器(Advise.class )与增强器是否匹配(instance);
2.根据找出的增强器创建代理。
匹配的过程为:如果方法中存在事务属性,则使用方法上的属性,否则使用方法所在的类上的属性,如果方法所在类的属性上还是没有搜寻到对应的事务属性,那么再搜寻接口中的方法,再没有的话,最后尝试搜寻接口的类上面的声明。而@Transaction则为事务属性的基础,还有其他的一些属性,如propagation、isolation等
注:在Spring 中,所有bean实例化时都会保证调用其postProcessAfterInitialization 方法,其实现是在AbstractAutoPorxyCreator此父类中
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
接下来注册的三个bean支撑起了事务功能,组织流程如下:
创建并注册TransactionAttributeSource的bean,生成beanName:sourceName,实例为AnnotationTransactionAttributeSource
创建并注册TransactionInterceptor的bean,生成beanName:interceptorName,实例为TransactionInterceptor
创建TransactionAttributeSourceAdvisor的bean:advisorDef,实例为BeanFactoryTransactionAttributeSourceAdvisor
将sourceName的bean注入advisorDef的transactionAttributeSource属性中
将interceptorName的bean注入advisorDef的adviceBeanName属性中
RootBeanDefinition sourceDef = new RootBeanDefinition(
"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
创建CompositeComponentDefinition
三个bean的组装图:
如此组装的目的是:因为BeanFactoryTransactionAttributeSourceAdvisor实现了Advisor接口,在获取增强器的时候也会将此bean提取出来,并随着其他增强器一起在后续的步骤中被织入代理,所以将TransactionInterceptor和AnnotationTransactionAttributeSource组装进去,就能提一而用三
总结:当判断某个bean适用于事务增强时,也就是适用于增强器BeanFactoryTransactionAbributeSourceAdvisor;BeanFactoryTransactionAbributeSourceAdvisor实现了Advisor接口,且因为TransactionInterceptor被组合进此类,所以,在调用事务增强器增强的代理类时会首先执行Transactionlnterceptor进行增强,同时在Transactionlnterceptor 类中的invoke方法中完成了整个事务的逻辑。
原文始发于微信公众号(不止于Java):《Spring源码深度解析》十(1)