spring4.3.6源代码 - tx - 命名空间处理器 & Processor

37 篇文章 0 订阅
21 篇文章 0 订阅

 

<tx:annotation-driven .../>

使用的是aop机制:
    ”advisor“、”拦截器“、”注解解析器“



<tx:annotation-driven transaction-manager="transactionManagerx" mode="proxy" /> 启动aop的功能,并注册aop的自定义Advisor对象到BeanDefinition容器
{
    1、注册 TransactionalEventListenerFactory 到 registry
    2、注册 hook
        1、配置 mode="proxy"
            1、注册 InfrastructureAdvisorAutoProxyCreator 到 registry 【BeanPostProcessor】
                如果有设置 proxy-target-class="",那么设置InfrastructureAdvisorAutoProxyCreator的属性
                    definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
                如果有设置 expose-proxy="",那么设置InfrastructureAdvisorAutoProxyCreator的属性
                    definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);

            2、注册 AnnotationTransactionAttributeSource  到 registry
                配置 AnnotationTransactionAttributeSource 的属性
                    sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

            3、注册 TransactionInterceptor  到 registry
                配置 TransactionInterceptor 的属性
                    interceptorDef.getPropertyValues().add("transactionManagerBeanName", TxNamespaceHandler.getTransactionManagerName(element));
                    interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
                    interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

            4、注册 BeanFactoryTransactionAttributeSourceAdvisor  到 registry
                配置 BeanFactoryTransactionAttributeSourceAdvisor 的属性
                    advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
                    advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
                    advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
                    advisorDef.getPropertyValues().add("order", element.getAttribute("order"));

        2、配置 mode="aspectj"
            注册 AnnotationTransactionAspect 到 registry
                配置 AnnotationTransactionAspect 的属性
                    def.setFactoryMethodName("aspectOf");
                    def.getPropertyValues().add("transactionManagerBeanName", TxNamespaceHandler.getTransactionManagerName(element));


}

 

// BeanPostProcessor
org.springframework.aop.aspectj.autoproxy.InfrastructureAdvisorAutoProxyCreator
{
    1、实例化前
    postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
    {

    }

    2、初始化后
    postProcessAfterInitialization(Object bean, String beanName)
    {
        return wrapIfNecessary(bean, beanName, cacheKey);
        {
            1、过滤不能被代理的
                1、 -- 实现Advice/Pointcut/Advisor/AopInfrastructureBean接口的类不能被代理
                2、 -- 要创建的是“接受通知的对象”,那么就要跳过了,不然陷入死循环

            2、getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null) --- 获取符合条件的“通知接受者”列表
                findEligibleAdvisors(Class<?> beanClass, String beanName)
                {
                    1、findCandidateAdvisors()
                    {
                        for(迭代所有实现Advisor接口的bean)
                        {
                            1、isEligibleBean(name)
                            {
                                isEligibleAspectBean(beanName)
                                {
                                    1、BeanDefinition的Role为ROLE_INFRASTRUCTURE
                                }
                            }
                        }
                    }

                    2、findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName) --- 匹配“通知接受者”列表
                    {
                        1、ClassFilter匹配
                        2、MethodMatcher匹配 - 《类中只要有一个方法能命中,就符合》
                    }

                    3、sortAdvisors(eligibleAdvisors) --- 对结果进行排序
                }

           3、创建代理对象 - 返回
                1、配置优化模式
                    new ObjenesisCglibAopProxy(config);

                2、没配置优化模式
                    new JdkDynamicAopProxy(config)
        }
    }
}

// "通知接收者"
org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor
{
    transactionAttributeSource : AnnotationTransactionAttributeSource, // 用于识别注解
    adviceBeanName : 对应拦截器
}

// 注解识别
org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
{
    // 注解 org.springframework.transaction.annotation.Transactional
    // 注解 javax.transaction.Transactional
    // 注解 javax.ejb.TransactionAttribute

    getTransactionAttribute(Method method, Class<?> targetClass) --- 获取事务属性
    {
        1、默认值识别public类型的方法(可配置)
        2、如果cglib生成的,那么定位到用户定义的实际类
        3、在“实现类的方法”上检查@Transactional注解信息,如果找到直接return
        4、在“实现类”上检查@Transactional注解信息,如果找到直接return
        5、在“接口类的方法”上检查@Transactional注解信息,如果找到直接return
        6、在“接口类”上检查@Transactional注解信息,如果找到直接return
    }
}

// 拦截器
org.springframework.transaction.interceptor.TransactionInterceptor
{
    invoke(final MethodInvocation invocation)
    {
        1、获取方法或者类上@Transactional配置的事务属性
        2、根据事务属性获取事务管理器
        3、执行事务
            TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); // 创建事务,如果需要。org.springframework.transaction.interceptor.TransactionAspectSupport.TransactionInfo
            {
                status = tm.getTransaction(txAttr); // 获取事务状态
                {
                    DefaultTransactionStatus status = newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); // 创建事务状态器
                    doBegin(transaction, definition); // 开启事务,禁止事务自动提交,把连接放入线程上下文
                }

                return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);  -- 用TransactionInfo包装TransactionStatus
                {
                    TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
                    txInfo.bindToThread();  // 把TransactionInfo绑定到当前线程上下文
                    return txInfo;
                }
            }

            Object retVal = null;
            try {
                retVal = invocation.proceedWithInvocation();  // 执行目标方法
            }
            catch (Throwable ex) {
                completeTransactionAfterThrowing(txInfo, ex);  // 根据异常配置进行“回滚、或者提交”
                throw ex;
            }
            finally {
                cleanupTransactionInfo(txInfo);
            }
            commitTransactionAfterReturning(txInfo); // 提交事务
            return retVal;
    }
}

 

配置拦截器

<tx:advice id="advice0" transaction-manager="transactionManagerx">
    <tx:attributes>
        <!-- MineRuntimeException的子类异常都回滚,除了MineSubOneRuntimeException异常的不回滚 -->
        <tx:method name="testException*"  rollback-for="cn.java.demo.txtag.real.exception.MineRuntimeException,cn.java.demo.txtag.real.exception.MineRuntimeException" 
                no-rollback-for="cn.java.demo.txtag.real.exception.MineSubOneRuntimeException,cn.java.demo.txtag.real.exception.MineSubOneRuntimeException"/> <!-- rollback-for和no-rollback-for,会依次匹配父类名的特征,谁最接近本类谁优先级较高  -->
        <tx:method name="find*"   propagation="NOT_SUPPORTED" isolation="REPEATABLE_READ" timeout="-1" read-only="true" /> <!-- propagation="NOT_SUPPORTED" 如果支持事务就使用事务执行,如果不支持事务就使用非事务执行 -->
        <tx:method name="insert*" propagation="REQUIRED" isolation="REPEATABLE_READ" timeout="10" read-only="false" /> <!-- propagation="REQUIRED" 如果存在事务就使用,如果不存在就创建 -->
        <tx:method name="delete*" propagation="REQUIRED" isolation="REPEATABLE_READ" timeout="-1" read-only="false" />
        <tx:method name="update*" propagation="REQUIRED" isolation="REPEATABLE_READ" timeout="-1" read-only="false" />
    </tx:attributes>
</tx:advice>

注册 TransactionInterceptor  到 registry
    配置 TransactionInterceptor 的属性
        interceptorDef.getPropertyValues().add("transactionManagerBeanName", TxNamespaceHandler.getTransactionManagerName(element));
        interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));

    

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值