spring声明式事务源码剖析(下)

对于spring声明式事务管理,我们已经剖析了一种,即应用spring配置xml文件,而这篇我们关注一下注解式事务管理。

对于注解式事务管理开启

<tx:annotation-driven transaction-manager="transactionManager"/>

它的解析(spring代码版本v.4.2.4.RELEASE):

  1. TxNamespaceHandler.init

    @Override
    public void init() {
        registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
        registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
        registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
    }
    
  2. AnnotationDrivenBeanDefinitionParser.parse

    /**
     * Parses the {@code <tx:annotation-driven/>} tag. Will
     * {@link AopNamespaceUtils#registerAutoProxyCreatorIfNecessary register an AutoProxyCreator}
     * with the container as necessary.
     */
    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        registerTransactionalEventListenerFactory(parserContext);
        String mode = element.getAttribute("mode");
        if ("aspectj".equals(mode)) {
            // mode="aspectj"
            registerTransactionAspect(element, parserContext);
        }
        else {
            // mode="proxy"
            AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
        }
        return null;
    }
    

    我们只看AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);

  3. AnnotationDrivenBeanDefinitionParser$AopAutoProxyConfigurer.configureAutoProxyCreator(Element element, ParserContext parserContext)

    这个方法主要生成一个切面:
    注入org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
    注入TransactionInterceptor 这个类我们已经很熟了;
    注入BeanFactoryTransactionAttributeSourceAdvisor生成切面,关于切面需要的pointcut则在该类里面直接实例化;
    
  4. org.springframework.transaction.annotation.AnnotationTransactionAttributeSource

    public AnnotationTransactionAttributeSource() {
        this(true);
    }
    
    /**
     * Create a custom AnnotationTransactionAttributeSource, supporting
     * public methods that carry the {@code Transactional} annotation
     * or the EJB3 {@link javax.ejb.TransactionAttribute} annotation.
     * @param publicMethodsOnly whether to support public methods that carry
     * the {@code Transactional} annotation only (typically for use
     * with proxy-based AOP), or protected/private methods as well
     * (typically used with AspectJ class weaving)
     */
    public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
        this.publicMethodsOnly = publicMethodsOnly;
        this.annotationParsers = new LinkedHashSet<TransactionAnnotationParser>(2);
        this.annotationParsers.add(new SpringTransactionAnnotationParser());
        if (jta12Present) {
            this.annotationParsers.add(new JtaTransactionAnnotationParser());
        }
        if (ejb3Present) {
            this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
        }
    }
    

    对于 spring的Transactional的注解解析则由SpringTransactionAnnotationParser来解决,代码如下。

  5. SpringTransactionAnnotationParser.parseTransactionAnnotation

    @Override
    public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
        AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, Transactional.class);
        if (attributes != null) {
            return parseTransactionAnnotation(attributes);
        }
        else {
            return null;
        }
    }
    

即所有注解了Transactional的方法或类或接口都被解析出来了,至此完.

猜你喜欢

转载自blog.csdn.net/zhurhyme/article/details/77650520
今日推荐