1.学习资料和书籍
2.代理的生成(原理)
3.代理的使用-使用中遇到的常见问题
涉及的源码类:
org.springframework.aop.config.AopNamespaceUtils
org.springframework.aop.config.AopConfigUtils
org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator
org.springframework.aop.framework.ProxyConfig
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
org.springframework.aop.support.AopUtils
org.springframework.aop.framework.ProxyFactory
org.springframework.transaction.config.TxNamespaceHandler
org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser
org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
org.springframework.transaction.interceptor.TransactionInterceptor
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction
org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor
1.学习资料和书籍
grepcode源码及相关博客
2.代理的生成
涉及事务代理的spring元素及特性:
xml配置:
2.1 <tx:annotation-driven transaction-manager="transactionManager" />
当XML中存在“<tx:annotation-driven/>”时,命名空间为tx。从相关的jar包(如spring-tx.jar)中可查看标签处理类。从配置文件spring.handlers中查找到的NamespaceHandler为org.springframework.transaction.config.TxNamespaceHandler
。由TxNamespaceHandler负责具体的解析tx命名空间
部分代码如下:
static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager"; static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager"; public void init() { registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser()); registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser()); registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser()); }
解析annotation-driven的类为org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser,源码可查看如下:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.transaction/3.2.2/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java?av=f
部分源码如下:
public static final String TRANSACTION_ADVISOR_BEAN_NAME = "org.springframework.transaction.config.internalTransactionAdvisor";
AnnotationDrivenBeanDefinitionParser#parse
public BeanDefinition parse(Element element, ParserContext parserContext) { String mode = element.getAttribute("mode"); if ("aspectj".equals(mode)) { // mode="aspectj" registerTransactionAspect(element, parserContext); } else { // mode="proxy" AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext); } return null; }
查看spring-tx-3.0.xsd可知,mode=proxy。内部类AopAutoProxyConfigurer为实际代理模式下引入aop框架,部分代码如下:
AopAutoProxyConfigurer.configureAutoProxyCreator方法分析:事务定义的入口
AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer#configureAutoProxyCreator
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) { AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element); String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME; if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) { Object eleSource = parserContext.extractSource(element); // Create the TransactionAttributeSource definition. RootBeanDefinition sourceDef = new RootBeanDefinition(AnnotationTransactionAttributeSource.class); sourceDef.setSource(eleSource); sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef); // Create the TransactionInterceptor definition. RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class); interceptorDef.setSource(eleSource); interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registerTransactionManager(element, interceptorDef); interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef); // Create the TransactionAttributeSourceAdvisor definition. RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class); advisorDef.setSource(eleSource); advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); 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); } }
创建InfrastructureAdvisorAutoProxyCreator的beanDefinition
a.定义后置处理器(InfrastructureAdvisorAutoProxyCreator)- 根据配置信息,定义生成代理的入口
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
创建事务代理的后置处理器InfrastructureAdvisorAutoProxyCreator
----------------------代码直译start----------------------
第一行:创建名为AUTO_PROXY_CREATOR_BEAN_NAME=org.springframework.aop.config.internalAutoProxyCreator的后置处理器InfrastructureAdvisorAutoProxyCreator( 实现了BeanPostProcessor),且名为AUTO_PROXY_CREATOR_BEAN_NAME的后置处理器只有一个
尚未注册,第三行注册
第二行:给AUTO_PROXY_CREATOR_BEAN_NAME设置属性
解析
PROXY_TARGET_CLASS_ATTRIBUTE = "proxy-target-class"
EXPOSE_PROXY_ATTRIBUTE = "expose-proxy"
设置后置处理器相关属性值
proxyTargetClass=true或
exposeProxy=true
(这2个属性在org.springframework.aop.framework.ProxyConfig中)
第三行:注册到容器
----------------------代码直译end----------------------
InfrastructureAdvisorAutoProxyCreator源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/autoproxy/InfrastructureAdvisorAutoProxyCreator.java#InfrastructureAdvisorAutoProxyCreator
AbstractAdvisorAutoProxyCreator源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java#AbstractAdvisorAutoProxyCreator
AbstractAutoProxyCreator源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java#AbstractAutoProxyCreator
执行InfrastructureAdvisorAutoProxyCreator
a.1 AbstractApplicationContext.refresh- 执行生成代理的入口,调用以上定义的入口生成代理
单一职责原则: AbstractAutoProxyCreator.postProcessAfterInitialization(Object bean, String beanName)(有图可知AbstractAutoProxyCreator为InfrastructureAdvisorAutoProxyCreator祖先类,祖先类中定义了模板方法),继续调用wrapIfNecessary方法
在实例化bean后,调用初始化方法后执行
该方法中:
(1)获取拦截器主要在后置处理器中完成 (2)创建代理委托给ProxyFactory完成
(1) 首先查找所有符合条件的Advisor类型的类(抽象方法:getAdvicesAndAdvisorsForBean)。
该任务委托由AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean完成(有图可知 AbstractAdvisorAutoProxyCreator为AbstractAutoProxyCreator的子类,InfrastructureAdvisorAutoProxyCreator的父类),继续调用findEligibleAdvisors,在该方法中,
(1.1)首先调用findCandidateAdvisors()方法,查找所有advisor类型的类
abstractAutoProxyCreator.postProcessAfterInitialization->abstractAutoProxyCreator.wrapIfNecessary->abstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean->abstractAdvisorAutoProxyCreator.findEligibleAdvisors->abstractAdvisorAutoProxyCreator.findCandidateAdvisors->advisorRetrievalHelper.findAdvisorBeans()->BeanFactoryUtils.beanNamesForTypeIncludingAncestors->beanFactory.getBean(name, Advisor.class)
advisorRetrievalHelper.findAdvisorBeans()方法中,循环advisorNames
BeanFactoryAdvisorRetrievalHelper源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/autoproxy/BeanFactoryAdvisorRetrievalHelper.java#BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans%28%29
(1.2)其次调用findAdvisorsThatCanApply()方法,查找所有上一步中符合条件的advisor。
abstractAutoProxyCreator.postProcessAfterInitialization->abstractAutoProxyCreator.wrapIfNecessary->abstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean->abstractAdvisorAutoProxyCreator.findEligibleAdvisors->abstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply->AopUtils.findAdvisorsThatCanApply->advisor.getPointCut->pointcut.matches->tas.getTransactionAttribute 最终返回符合条件的advisor
AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass)方法,
该方法中循环candidateAdvisors,调用canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions),根据advisor获取pointcut,继续调用canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions),通过pc.getMethodMatcher()获取methodMatcher,这个类是真正判断该类或方法适合符合事物,即该类或方法是否有@Transaction注释
如果bean不适合该advisor,即没有@Transaction注释,则返回false,并将该bean放入this.advisedBeans.put(cacheKey, Boolean.FALSE),并最终返回bean
否则创建代理,(1)最终过滤符合条件的拦截器specificInterceptors
对于BeanFactoryTransactionAttributeSourceAdvisor持有对象TransactionAttributeSourcePointcut,具体分析见(d)
(2) 创建代理AopProxy,并通过aopProxy.getProxy返回最终代理bean。
abstractAutoProxyCreator.postProcessAfterInitialization->abstractAutoProxyCreator.wrapIfNecessary->abstractAutoProxyCreator.createProxy->proxyFactory.getProxy->proxyFactory.createAopProxy().getProxy->jdkDynamicAopProxy.getProxy或cglibProxy.getProxy->java.lang.reflect.Proxy.newProxyInstance(classLoader, proxiedInterfaces, this): 最终返回proxy
this即为aopProxy(jdkDynamicAopProxy或cglibProxy)其实现了InvocationHandler接口
proxy何时调用?
用户业务对象的代理调用时,最终调用invocationHandler.invoke方法
通过jdkDynamicAopProxy源码了解其invoke方法
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/JdkDynamicAopProxy.java#JdkDynamicAopProxy
abstractAutoProxyCreator.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)),在该方法中创建 ProxyFactory,并设置属性
ProxyFactory源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/ProxyFactory.java#ProxyFactory.getProxy%28java.lang.ClassLoader%29
ProxyFactory proxyFactory = new ProxyFactory(); // Copy our properties (proxyTargetClass etc) inherited from ProxyConfig. proxyFactory.copyFrom(this); if (!shouldProxyTargetClass(beanClass, beanName)) { // Must allow for introductions; can't just set interfaces to // the target's interfaces only. Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader); for (Class<?> targetInterface : targetInterfaces) { proxyFactory.addInterface(targetInterface); } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); for (Advisor advisor : advisors) { proxyFactory.addAdvisor(advisor); } proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(this.proxyClassLoader);
最后一句proxyFactory.getProxy(this.proxyClassLoader);此处创建代理。
public Object getProxy(ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); }
该方法中createAopProxy()返回AopProxy如下:
proxyCreatorSupport.createAopProxy()创建代理
protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); }
getAopProxyFactory()方法中获取ProxyCreatorSupport的内置对象aopProxyFactory( new DefaultAopProxyFactory())。
DefaultAopProxyFactory源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/DefaultAopProxyFactory.java#DefaultAopProxyFactory
getAopProxyFactory().createAopProxy(this)该方法返回AopProxy
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface()) { return new JdkDynamicAopProxy(config); } return CglibProxyFactory.createCglibProxy(config); } else { return new JdkDynamicAopProxy(config); } }
createAopProxy().getProxy(classLoader);以jdk生成代理为例
jdkDynamicAopProxy.getProxy(classLoader)
public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }
最终返回代理对象
JdkDynamicAopProxy源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/JdkDynamicAopProxy.java#JdkDynamicAopProxy
此后置处理器处理@Transaction注释的bean,创建aopProxy。其他advisor如何处理,事务代理的外面再加一层代理?
尝试解释:
该后置处理器可以处理多个advisor(包括事务advisor,即BeanFactoryTransactionAttributeSourceAdvisor)
自定义advisor,实现相应接口,看否是可以识别?
自定义beanpostprocess,在此前代理上创建代理或者覆盖原先代理对象?
ProxyCreatorSupport源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/ProxyCreatorSupport.java#ProxyCreatorSupport.createAopProxy%28%29
断点2
创建AnnotationTransactionAttributeSource的beanDefinition
b.定义AnnotationTransactionAttributeSource- 事务属性,每个业务类或方法可能不同,大部分是一样的
// Create the TransactionAttributeSource definition. RootBeanDefinition sourceDef = new RootBeanDefinition(AnnotationTransactionAttributeSource.class); sourceDef.setSource(eleSource); sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
创建 AnnotationTransactionAttributeSource定义(事务属性来源于注解@Transactional)
单一职责原则:getTransactionAttribute(Method method, Class<?> targetClass)
判断方法或类是否有@Transactional注释,并解析返回TransactionAttribute或null。其内部调用SpringTransactionAnnotationParser来解析是否有@Transactional注解
AnnotationTransactionAttributeSource源码见:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.transaction/3.2.2/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java?av=f
在哪调用其getTransactionAttribute(Method method, Class<?> targetClass)方法,以获取事务属性?
(1) 在后置处理器,avvisor->pointcut.matches->getTransactionAttribute,用于判断advisor适合适合此bean
(2) 在TransactionInterceptor的invoke方法中调用,更确切的说是在TransactionAspectSupport的invokeWithinTransaction方法中。用于事务定义TransactionInfo
用于判断该方法或类是否可开启事务。
还有其他的事务属性来源,应用于不同的事务配置方式如:NameMatchTransactionAttributeSource
创建TransactionInterceptor的beanDefinition
c.定义TransactionInterceptor- 事务拦截器,执行事务开始,提交,回滚等操作
// Create the TransactionInterceptor definition. RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class); interceptorDef.setSource(eleSource); interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registerTransactionManager(element, interceptorDef); interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
创建TransactionInterceptor定义
单一职责原则:invoke(final MethodInvocation invocation)
invoke中调用TransactionAspectSupport的invokeWithinTransaction(Method method, Class targetClass, final InvocationCallback invocation)方法,执行真正的拦截逻辑。在该方法中会调用transactionAttributeSource判断类或方法是否可开启事务,调用transactionManager执行拦截逻辑,即开启提交事务等。
registerTransactionManager(element, interceptorDef);
这行代码,主要是设置TransactionAspectSupport的transactionManager(注册事务管理器)。调用invoke时,设置到生成的TransactionInfo中并管理事务状态。
TransactionInterceptor(拦截器)本身不保存数据,只是起到传递的作用,把真正的处理过程交给TransactionAspectSupport 去完成
在哪调用TransactionInterceptor.invoke(final MethodInvocation invocation)?
在(a)处后置处理器中,生成代理(jdk或cglib代理),invoke方法中调用
transactionInterceptor是advice,是否包装成advisor何时包装?
创建代理时(a(2))封装成advisor:
abstractAutoProxyCreator.buildAdvisors->advisorAdapterRegistry.wrap
调用代理方法时,执行的是methodInterceptor,advisor何时拆解成methodInterceptor?
执行代理方法invoke时,通过advised.getInterceptorsAndDynamicInterceptionAdvice获取methodInterceptor,其中会调用advisorAdapterRegistry.getInterceptors(advisor);
TransactionAspectSupport源码可见:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.transaction/3.2.2/org/springframework/transaction/interceptor/TransactionAspectSupport.java#TransactionAspectSupport.TransactionInfo.bindToThread%28%29
joinpointIdentification
TransactionInterceptor源码见:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.transaction/3.2.2/org/springframework/transaction/interceptor/TransactionInterceptor.java#TransactionInterceptor
创建BeanFactoryTransactionAttributeSourceAdvisor的beanDefinition
d.定义BeanFactoryTransactionAttributeSourceAdvisor- 事务集成到业务bean,连接中介类
// Create the TransactionAttributeSourceAdvisor definition. RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class); advisorDef.setSource(eleSource); advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); 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);
创建TransactionAttributeSourceAdvisor定义
BeanFactoryTransactionAttributeSourceAdvisor源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.transaction/3.2.2/org/springframework/transaction/interceptor/BeanFactoryTransactionAttributeSourceAdvisor.java?av=f
BeanFactoryTransactionAttributeSourceAdvisor是一个标识类,使其能够被后置处理器(InfrastructureAdvisorAutoProxyCreator见(a)出分析)识别。
具体分析见:
http://www.cnblogs.com/youzhibing/p/6414780.html
持有对象TransactionAttributeSourcePointcut
public boolean matches(Method method, Class targetClass) { TransactionAttributeSource tas = getTransactionAttributeSource(); return (tas == null || tas.getTransactionAttribute(method, targetClass) != null); }
后置处理器中调用此方法,判断bean或method是否适合此advisor
TransactionAttributeSourcePointcut源码见
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.transaction/3.1.2/org/springframework/transaction/interceptor/TransactionAttributeSourcePointcut.java#TransactionAttributeSourcePointcut
创建CompositeComponentDefinition的beanDefinition
e.定义组件之间的关系bean
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);
该类的具体作用是什么?
定义事务处理之间的关系?
断点4:
总结:
条件语句里面创建了3个bean定义(TransactionAttributeSource ,TransactionInterceptor,TransactionAttributeSourceAdvisor ),将3个类组合嵌入compositeDef中,代表整个<tx:annotation-driven transaction-manager="transactionManager" />
还创建了一个后置处理器,bean实例化后,创建事务代理
创建3个定义或者后置处理器的过程中,多处可以继续跟踪代码,如如何创建aopProxy代理,transactioninterceptor中的invoke方法是如何执行的等等。限于篇幅,这里进一步跟踪,后续补上
2.2 @Transactionl
事务属性来源,主要在TransactionAttributeSource中判断bean或者method中是否有注解
3.代理的使用-使用中遇到的常见问题
参考:
https://www.ibm.com/developerworks/cn/education/opensource/os-cn-spring-trans/
http://www.myexception.cn/open-source/1942796.html
http://www.codeceo.com/article/software-outsourcing-and-lover.html
http://blog.csdn.net/qq418517226/article/details/51282035
http://jinnianshilongnian.iteye.com/blog/1901694
http://www.cnblogs.com/wade-luffy/p/6080183.html Spring事务解析2-标签解析
http://jinnianshilongnian.iteye.com/blog/1508018 TransactionAttributeSource
http://lgbolgger.iteye.com/blog/2180251 Spring事务源码分析(一)Spring事务入门