码迷,mamicode.com
首页 > 编程语言 > 详细

SpringAOP——事务实现细节

时间:2020-03-21 17:49:34      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:alt   figure   mda   action   join   nec   根据   ica   isa   

承接上文,<tx:annotation-driven />开启声明式事务时,在SpringIOC容器中初始化了4个Bean

    <!-- 事务管理 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 启用声明式事务管理 支持注解@Transaction-->
    <tx:annotation-driven proxy-target-class="false" transaction-manager="transactionManager"/>
TransactionalEventListenerFactory
AnnotationTransactionAttributeSource
TransactionInterceptor//SpringAOP方法执行时的责任链拦截器
BeanFactoryTransactionAttributeSourceAdvisor//直接用bean创建的Advisor

由于前面没有具体深入了解每个Bean的作用以及实现,所以面试被难住了,补充一下Spring事务的具体实现。弄清楚三点:

  • 每个组件的作用
  • 事务的实现流程
  • 与Mybatis的对接实现

一、组件初始化

/*  org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser#registerTransactionalEventListenerFactory */
    private void registerTransactionalEventListenerFactory(ParserContext parserContext) {
        //创建TransactionEvenListenerFactory的Beandefinition
        RootBeanDefinition def = new RootBeanDefinition();
        def.setBeanClass(TransactionalEventListenerFactory.class);
        parserContext.registerBeanComponent(new BeanComponentDefinition(def,
                TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME));
    }

/* org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer#configureAutoProxyCreator */
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
            //若未注册,先注册SpringAOP相关Beandefinition
            AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);

            String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
            if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
                Object eleSource = parserContext.extractSource(element);

                //Source的Beandefinition
                //beanName = org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0
                RootBeanDefinition sourceDef = new RootBeanDefinition(
                        "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
                //实际eleSource == null
                sourceDef.setSource(eleSource);
                sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
                //sourceName == org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0
                String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

                //Inteceptor的BeanDefinition
                //beanName=org.springframework.transaction.interceptor.TransactionInterceptor#0
                RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
                interceptorDef.setSource(eleSource);
                interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
                //初始化时的重要信息,设置TransactionInterceptor的属性trancationManagerBeanName的beanName,初始化时依赖注入
                //实际获取<tx:annotation-driven transaction-manager="" >中的transaction-manage属性,默认值:beanName = transactionManager
                registerTransactionManager(element, interceptorDef);
                //TransactionInterception.trancationAttributeSource = AnnotationTransactionAttributeSource
                interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
                //interceptorName = org.springframework.transaction.interceptor.TransactionInterceptor#0
                String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
                
                //advisor的BeanDefinition
                //beanName = org.springframework.transaction.config.internalTransactionAdvisor
                RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
                advisorDef.setSource(eleSource);
                advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
                //设置两个属性
                //advisor.transactionAttributeSource = AnnotationTransactionAttributeSource的beanName
                //advisor.adviceBeanName = TransactionInterceptor的beanName
                advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
                advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
                if (element.hasAttribute("order")) {
                    advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
                }
                //将组件的BeanDefinition注册到DefaultListableBeanFactory中
                parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
                
                CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
                compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
                compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
                compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
                parserContext.registerComponent(compositeDef);
            }
        }

总结下组件的依赖关系:

//Inteceptor
TransactionInterceptor.trancationManagerBeanName = "transactionManager"
TransactionInterceptor.transactionAttributeSource = AnnotationTransactionAttributeSource
//advisor
advisor.transactionAttributeSource = AnnotationTransactionAttributeSource
advisor.advice = TransactionInterceptor 

二、事务的AOP实现

SpringAOP实现流程:

① <aop:aspectj-autoproxy />开启SpringAOP代理支持后,会初始化AOP相关组件AnnotationAwareAspectJAutoProxyCreator

② 所有的Bean在初始化的最后阶段都会调用AnnotationAwareAspectJAutoProxyCreator.postprocessAfterInitialzation,判断是否需要生成代理类

③ List<Advisor> candidateAdvisors = findCandidateAdvisors();查找所有Advisor,

④ List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);Bean是否是切面关注点的判断,从所有advisor保留对应的advisor,

⑤ advisor不为空则会创建代理实例proxy object,为空不创建代理,直接返回原实例 target object

⑥ 创建一个ProxyFactory实例记录advisor,将ProxyFactory放入到InvocationHandler实例(jdk动态代理对应JdkDynamicAopProxy)中

⑦ 方法调用时,通过动态代理实现,调用代理类的方法,实际是调用InvocationHandler.invoke()方法(jdk动态代理对应JDKDynamicAopProxy.invoke)

⑧ invocationHandler.invoke具体是实现是:从proxyFactory中找到对应的advisor,然后调用advisor.getAdvice获取具体的advice操作侯然先执行advice后执行target object的方法

事务的实现流程是基于SpringAOP实现的。

1、@Transactional注解扫描,

对应流程③查找所有的advisor,会找到BeanFactoryTransactionAttributeSourceAdvisor

对应流程④Bean是否是切面关注点,根据BeanFactoryTransactionAttributeSourceAdvisor中的Pointcut判断,实际判断是否被@Transaction注解修饰

/* org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor#getPointcut */
    /*
    * BeanFactoryTransactionAttributeSourceAdvisor中的pointCut初始化
    */
    public Pointcut getPointcut() {
        return this.pointcut;
    }

    //pointCut实际是一个TransactionAttributeSourcePointcut实例
    private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
        @Override
        @Nullable
        protected TransactionAttributeSource getTransactionAttributeSource() {
            return transactionAttributeSource;
        }
    };

    protected TransactionAttributeSourcePointcut() {
        setClassFilter(new TransactionAttributeSourceClassFilter());
    }

    private class TransactionAttributeSourceClassFilter implements ClassFilter {
        //判断Bean是否是poincut的一个join point(切面关注点)
        @Override
        public boolean matches(Class<?> clazz) {
            if (TransactionalProxy.class.isAssignableFrom(clazz) ||
                    PlatformTransactionManager.class.isAssignableFrom(clazz) ||
                    PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
                //三种基础类型直接返回false
                return false;
            }
            //这里tas就是上面设置的AnnotationTrancationAttributeSource
            TransactionAttributeSource tas = getTransactionAttributeSource();
            return (tas == null || tas.isCandidateClass(clazz));
        }
    }

AnnotationTrancationAttributeSource.isCandidateClass():

/* org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#isCandidateClass */
    public boolean isCandidateClass(Class<?> targetClass) {
        for (TransactionAnnotationParser parser : this.annotationParsers) {
            if (parser.isCandidateClass(targetClass)) {
                return true;
            }
        }
        return false;
    }

    //annotationParsers初始化
    //annotationParsers.add(new SpringTransactionAnnotationParser())
    //系统支持jta12时annotationParsers.add(new SpringTransactionAnnotationParser())
    //系统支持ejb3时this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
    public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
        this.publicMethodsOnly = publicMethodsOnly;
        if (jta12Present || ejb3Present) {
            this.annotationParsers = new LinkedHashSet<>(4);
            this.annotationParsers.add(new SpringTransactionAnnotationParser());
            if (jta12Present) {
                this.annotationParsers.add(new JtaTransactionAnnotationParser());
            }
            if (ejb3Present) {
                this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
            }
        }
        else {
            this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());
        }
    }

    //默认的SpringTransactionAnnotationParse.isCandidateClass
    //判断类中包含@Transactional注解,
    public boolean isCandidateClass(Class<?> targetClass) {
        return AnnotationUtils.isCandidateClass(targetClass, Transactional.class);
    }

对应流程⑤ 被@Transactional注解修饰的类的Bean,advisor =  BeanFactoryTransactionAttributeSourceAdvisor,不为空创建代理实例

对应流程⑥ 将advisor放入到创建ProxFactory实例的advisors容器中

对应流程⑦ ⑧方法调用时获取BeanFactoryTransactionAttributeSourceAdvisor.getAdvice(),先执行advice.invoke,再执行target object.invoke。即开启事务执行sql提交(失败回退)。这里BeanFactoryTransactionAttributeSourceAdvisor.getAdvice()=TransactionInterceptor

TransactionInterceptor.invoke()

/* org.springframework.transaction.interceptor.TransactionInterceptor#invoke */
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // target object可能为null,所以这里获取targetClass
        //如果存在targetObject时 targetClass = targetObject.getClass
        //如果不存在targetObject时 targetClass = null
        //注意了mybatis接口绑定技术是没有targetObject的,这里targetClass == null
        Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

        // 事务执行 
        // 第三个参数lamda表达式:invocation.proceed()
        return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
    }

TransactionAspectSupport.invokeWithinTransaction()

 

 

 

SpringAOP——事务实现细节

标签:alt   figure   mda   action   join   nec   根据   ica   isa   

原文地址:https://www.cnblogs.com/wqff-biubiu/p/12540147.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!