Spring事务切面生成原理

一、前言

本节我们来谈谈 标签如何创建事务切面的。

二、 标签如何创建事务切面的

首先 标签作用是创建一个TransactionInterceptor,作为事务切面的通知方法 在Spring中(可以参考:https://gitbook.cn/gitchat/activity/5a8fdf6bf2e5dc2ca621a937) Advisor这个概念是从 Spring 1.2的 AOP 支持中提出的,一个 Advisor 相当于一个小型的切面,不同的是它只有一个通知(Advice),Advisor中还包含一个pointcut(切点),切点定义了对那些方法进行拦截,而通知是具体对拦截到的方法进行增强的逻辑。

具体对 标签进行解析的是TxAdviceBeanDefinitionParser,其时序图如下:

Spring事务切面生成原理_第1张图片

首先TxAdviceBeanDefinitionParser有getBeanClass方法代码代码:

    protected Class<?> getBeanClass(Element element) {	
        return TransactionInterceptor.class;	
    }

这说明该标签解析后生成的是TransactionInterceptor对象的bean定义。

  • 其中时序图中步骤(2)是设置配置demo的XML配置文件里面创建的事务管理器到TransactionInterceptor对象,Spring事务切面生成原理_第2张图片

  • 时序图(4)~(10)则解析 标签中事务属性值设置到TransactionInterceptor对象里面属性里面。

注:也就是 标签的作用是生成一个TransactionInterceptor拦击器对象,并设置该对象的一些事务属性,然后该对象将作为事务切面的通知方法。

然后 标签作用是创建一个DefaultBeanFactoryPointcutAdvisor(其实现了Advisor接口)对象作为作一个Advisor,前面说了一个Advisor就是一个小型的切面,所以其中定义了切点和通知。该标签是ConfigBeanDefinitionParser类进行解析的,其时序图如下:Spring事务切面生成原理_第3张图片

  • 时序图中步骤(2)创建了一个DefaultBeanFactoryPointcutAdvisor对象的bean定义,步骤(3)(4)则是设置上面创建的通知对象(TransactionInterceptor)到该Advisor

  • 时序图中步骤(8)则是解析标签中的切点表达式,然后设置到DefaultBeanFactoryPointcutAdvisor对象的bean定义。

  • 时序图步骤(4)注册了一个AspectJAwareAdvisorAutoProxyCreator到Spring容器,作用就是对满足pointcut表达式的类的方法进行代理,并且使用advice进行拦截处理,而advice就是事务拦截器。

由于AspectJAwareAdvisorAutoProxyCreator类实现了BeanPostProcessor接口,所以具有postProcessAfterInitialization方法,而对符合切点的方法进行代理就是在该方法内的wrapIfNecessary方法:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {	
        ...	
        // 8.1	
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);	
        if (specificInterceptors != DO_NOT_PROXY) {	
            this.advisedBeans.put(cacheKey, Boolean.TRUE);	
            //8.2	
            Object proxy = createProxy(	
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));	
            this.proxyTypes.put(cacheKey, proxy.getClass());	
            return proxy;	
        }	
	
        this.advisedBeans.put(cacheKey, Boolean.FALSE);	
        return bean;	
    }

其中8.1查找所有可以对当前bean进行增强的切面,其中有一个条件就是看那些bean实现了Advisor接口,而 标签作用是创建一个DefaultBeanFactoryPointcutAdvisor,并且其实现了Advisor接口,所以这里会使用DefaultBeanFactoryPointcutAdvisor切面,然后会看当前bean的方法是否满足切面的切点表达式,具体是AopUtils的canApply方法进行判断:Spring事务切面生成原理_第4张图片

如果满足则执行8.2对方法进行代理,这里会对TestTransactionProgagationUserImpl、TestTransactionProgagationCourseImpl、UserManagerBoImpl类的所有方法进行事务代理。

注:Spring框架中一个 Advisor 相当于一个小型的切面, 定义了这个切面的通知方法,而 具体定义了一个Advisor切面,并且内部定义了一个切点,并且引入了 定义的通知方法

最后

  • 推荐大家几个能够拓展我们视野的课程

       推荐精品课程

  • Dubbo专题

    单击下方阅读原文

你可能感兴趣的:(Spring事务切面生成原理)