《Spring源码深度解析》十(1)

>>强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!

第十章:事务

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的组装图:

《Spring源码深度解析》十(1)

如此组装的目的是:因为BeanFactoryTransactionAttributeSourceAdvisor实现了Advisor接口,在获取增强器的时候也会将此bean提取出来,并随着其他增强器一起在后续的步骤中被织入代理,所以将TransactionInterceptor和AnnotationTransactionAttributeSource组装进去,就能提一而用三

总结:当判断某个bean适用于事务增强时,也就是适用于增强器BeanFactoryTransactionAbributeSourceAdvisor;BeanFactoryTransactionAbributeSourceAdvisor实现了Advisor接口,且因为TransactionInterceptor被组合进此类,所以,在调用事务增强器增强的代理类时会首先执行Transactionlnterceptor进行增强,同时在Transactionlnterceptor 类中的invoke方法中完成了整个事务的逻辑。


原文始发于微信公众号(不止于Java):《Spring源码深度解析》十(1)