xml解析
与spring IoC容器的初始化时xml解析和spring AOP的xml解析一样,spring事务部分的xml解析同样是在BeanDefinitionParserDelegate类的parseCustomElement方法中执行的,spring事务部分所对应的命名空间为http://www.springframework.org/schema/tx。
里面对应的解析器如下:
元素名 |
解析器 |
advice |
TxAdviceBeanDefinitionParser |
jta-transaction-manager |
JtaTransactionManagerBeanDefinitionParser |
annotation-driven |
AnnotationDrivenBeanDefinitionParser |
由于主要阅读的是注解方式的事务实现,其对应的标签元素为annotation-driven,那么它所对应的解析器即为AnnotationDrivenBeanDefinitionParser。
打开解析方法,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
public BeanDefinition parse(Element element, ParserContext parserContext) { String mode = element.getAttribute("mode"); if ("aspectj".equals(mode)) { registerTransactionAspect(element, parserContext); } else { AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext); } return null; }
|
打开调试我们可以发现对于我们的xml配置,默认存在如下两个属性:
1 2
| mode="proxy" proxy-target-class="false"
|
对于proxy-target-class属性,如果有看过之前的AOP部分,就清楚true表示强制使用cglib作为代理实现方式。
其中mode属性为proxy表示使用代理的方式来实现事务,为aspectj则表示时用aspectj的方式来实现事务。其中代理的方式是通过spring AOP来实现的。至于proxy与aspectj的差异,可以查看这篇文章Java JDK代理、CGLIB、AspectJ代理分析比较。
我们此处来看proxy的解析方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) { AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element); String txAdvisorBeanName = "org.springframework.transaction.config.internalTransactionAdvisor"; if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) { Object eleSource = parserContext.extractSource(element); RootBeanDefinition sourceDef = new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"); sourceDef.setSource(eleSource); sourceDef.setRole(2); String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef); RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class); interceptorDef.setSource(eleSource); interceptorDef.setRole(2); AnnotationDrivenBeanDefinitionParser.registerTransactionManager(element, interceptorDef); interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef); RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class); advisorDef.setSource(eleSource); advisorDef.setRole(2); advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); advisorDef.getPropertyValues().add("adviceBeanName", interceptorName); if (element.hasAttribute("order")) { advisorDef.getPropertyValues().add("order", element.getAttribute("order")); }
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); }
}
|
我们继续来看看其第一部分的注册AutoProxyCreator的源码,
1 2 3 4 5 6 7 8 9 10
|
public static void registerAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); registerComponentIfNecessary(beanDefinition, parserContext); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) { return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source); }
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) { if (sourceElement != null) { boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE)); if (proxyTargetClass) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE)); if (exposeProxy) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } }
|
最后一个registerComponentIfNecessary是用来注册AutoProxyCreator组件的。
我们可以发现整个注册AutoProxyCreator其实就是使用了AOP,应该说在没有AOP的情况下,会创建一个自己的AOP。
那么我们最终对proxy的解析方式做一个梳理,如下:
- 注册AutoProxyCreator(主要是用来创建代理的,具体作用可以详见spring AOP部分的博客。此处若是已经存在AutoProxyCreator,比如AOP的,则使用优先级高的那个)
- 创建internalTransactionAdvisor
- 其事务属性源设置为AnnotationTransactionAttributeSource
- 通知(advice)设置为TransactionInterceptor
- order设置为xml中配置的order属性
- 将tx:annotation-driven注册为组件