对于spring声明式事务管理,我们已经剖析了一种,即应用spring配置xml文件,而这篇我们关注一下注解式事务管理。
对于注解式事务管理开启
<tx:annotation-driven transaction-manager="transactionManager"/>
它的解析(spring代码版本v.4.2.4.RELEASE):
TxNamespaceHandler.init
@Override public void init() { registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser()); registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser()); registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser()); }
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);
AnnotationDrivenBeanDefinitionParser$AopAutoProxyConfigurer.configureAutoProxyCreator(Element element, ParserContext parserContext)
这个方法主要生成一个切面: 注入org.springframework.transaction.annotation.AnnotationTransactionAttributeSource 注入TransactionInterceptor 这个类我们已经很熟了; 注入BeanFactoryTransactionAttributeSourceAdvisor生成切面,关于切面需要的pointcut则在该类里面直接实例化;
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来解决,代码如下。
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的方法或类或接口都被解析出来了,至此完.