- 浏览: 50382 次
- 性别:
- 来自: 南京
文章分类
最新评论
本文主要分析spring事务代理的源码,跟踪代码,了解事务代理的生命周期
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命名空间
部分代码如下:
解析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
部分源码如下:
AnnotationDrivenBeanDefinitionParser#parse
查看spring-tx-3.0.xsd可知,mode=proxy。内部类AopAutoProxyConfigurer为实际代理模式下引入aop框架,部分代码如下:
AopAutoProxyConfigurer.configureAutoProxyCreator方法分析:事务定义的入口
AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer#configureAutoProxyCreator
创建InfrastructureAdvisorAutoProxyCreator的beanDefinition
a.定义后置处理器(InfrastructureAdvisorAutoProxyCreator)-根据配置信息,定义生成代理的入口
创建事务代理的后置处理器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.getProxy(this.proxyClassLoader);此处创建代理。
该方法中createAopProxy()返回AopProxy如下:
proxyCreatorSupport.createAopProxy()创建代理
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
createAopProxy().getProxy(classLoader);以jdk生成代理为例
jdkDynamicAopProxy.getProxy(classLoader)
最终返回代理对象
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-事务属性,每个业务类或方法可能不同,大部分是一样的
创建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-事务拦截器,执行事务开始,提交,回滚等操作
创建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,连接中介类
创建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
后置处理器中调用此方法,判断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
该类的具体作用是什么?
定义事务处理之间的关系?
断点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事务入门
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事务入门
发表评论
-
spring疑难解惑-循环依赖的解决
2020-06-17 23:27 541AbstractAutowireCapableBeanFact ... -
spring容器
2019-07-14 08:47 305private final ServletContainer ... -
spring容器
2019-07-13 23:35 0spring容器与springmvc容器 73 ... -
spring源码学习系列2.6-spring ioc原理-codes
2019-03-05 22:56 487web.xml <listener> < ... -
spring源码学习系列3.4-spring mvc原理-codes
2019-01-21 22:46 296本篇章从核心类角度解读springmvc的原理 web.xm ... -
spring源码学习系列4.2-spring aop原理-codes
2018-12-04 22:29 561jdk: Proxy InvocationHandler ... -
spring源码学习系列4.1-spring实现对ibatis的事务管理
2018-09-17 15:44 578事务由spring管理,可以理解为由spring管理数据库连接 ... -
spring源码学习系列4-3种常用的自动代理创建器
2018-09-02 15:48 5703种自动代理器是 AnnotationAwareAspectJ ... -
spring源码学习系列1.2-spring事务代理深入分析2
2018-05-27 19:46 451提示: BeanPostProcessor AopUtils ... -
spring源码学习系列2.5-ApplicationContext初始化-设计模式
2018-05-08 15:17 519ApplicationContext容器的初始化可以通过模板方 ... -
spring源码学习系列3.3-DispatcherServlet初始化-设计模式
2018-05-07 11:12 622springmvc的核心是DispatcherServlet ... -
封装spring-security
2018-01-23 19:33 518github地址: https://github.com/ne ... -
eclipse导入spring源码
2018-05-12 07:20 980spring在git上的项目时gradle管理jar包的,所以 ... -
spring源码学习系列3.2.3-异常页面拦截机制
2017-07-29 19:07 767前序:本文的意义在于了解 tomcat处理异常 请求访问 ... -
spring源码学习系列3.2.2-How to bind String to Date
2017-07-17 12:40 597springmvc开发中,经常需将界面日期数据(String) ... -
spring源码学习系列3.2.1-command对象的绑定
2017-05-28 12:00 981在<spring源码学习系列3.2-handlerAda ... -
spring源码学习系列3.2-handlerAdapter执行
2017-05-28 12:01 409DispatcherServlet#doDispatch中调用 ... -
spring源码学习系列3.1-handlerMapping初始化
2017-05-28 11:56 701SimpleUrlHandlerMapping的继承体系 or ... -
spring源码学习系列2.4-finishRefresh会做什么
2017-05-06 16:36 578spring容器初始化完成后,调用finishRresh 该 ... -
spring源码学习系列3-springmvc原理
2017-05-28 11:56 456问题: springmvc是如何控 ...
相关推荐
《Spring框架1.0源码解析》 Spring框架,作为Java企业级应用开发的重要支柱,自2003年发布以来,已经历了多个版本的迭代,为开发者...通过深入学习,我们可以更好地利用Spring的强大功能,提高软件开发的质量和效率。
深入理解Spring源码需要对Java反射、动态代理、设计模式等有扎实的基础。建议从以下几个步骤入手: 1. 了解基本架构和模块划分。 2. 分析核心类如ApplicationContext、BeanFactory和DispatcherServlet的实现。 3. ...
总的来说,Spring框架5.2.8.RELEASE源码的学习是一次深入理解Java企业级开发、掌握模块化设计和面向切面编程理念的宝贵机会。通过深入研究源码,开发者可以提升自己的编程技巧,为开发高质量的、可维护的应用程序...
通过阅读和分析Spring 1.2.6的源码,不仅可以学习到Spring的核心设计原则,还能了解到设计模式的运用,例如工厂模式、单例模式、观察者模式等。同时,这也是提升Java编程技巧和理解框架底层运作的好机会。在实际的...
《Spring源码分析》这份资料深入探讨了Spring框架的核心机制,尤其聚焦于Spring5版本。Spring作为Java领域中最重要的轻量级应用框架之一,它的设计理念、实现方式以及工作原理对于任何想成为优秀Java开发者的人都至...
总的来说,深入学习Spring Framework 5.2.9.RELEASE的源码,不仅可以帮助我们更好地利用这个框架,还能提升我们的编程水平和系统设计能力,从而在实际项目中游刃有余。通过细致研究每个模块的功能和实现细节,我们...
通过深入学习Spring Framework 5.2.15.RELEASE的源码,开发者不仅可以提升自身的技术能力,也能更好地利用Spring框架解决实际开发中遇到的问题,提高代码质量和开发效率。在后续的开发过程中,对源码的理解也会为...
《Spring Framework 5.1.4源码深度解析》 Spring Framework是Java开发中的核心框架,它为构建高质量的企业级应用提供了全面的...通过深入研究源码,我们可以学习到软件设计的最佳实践,提升我们的编程技巧和架构能力。
深入学习Spring Data Hadoop的源码,不仅可以帮助我们更好地理解和使用这个库,还能提升我们对Hadoop生态系统的理解。源码中的注释和设计模式将引导我们深入到Hadoop的内部工作原理,同时也会展示Spring如何通过其...
《深入剖析Spring Framework 5.1.13.RELEASE...通过深入学习Spring Framework 5.1.13.RELEASE的源码,不仅可以提高我们的技术水平,也能帮助我们在实际项目中更好地利用Spring提供的功能,提升软件开发的效率和质量。
【Spring 框架概述】 Spring 是一个广泛使用的开源 Java 应用开发框架,它的核心目标是简化企业级应用的开发。...通过深入学习 Spring 源码,开发者可以更好地理解其工作原理,进一步优化和定制应用的实现。
"spring系列教程博客源码-东离与糖宝"很显然是一份关于Spring框架的教程资源,其中可能包含了详细的代码示例、解释以及教学内容,旨在帮助学习者深入理解和掌握Spring的核心功能和使用技巧。 1. **Spring核心概念**...
本文将深入探讨Spring事务管理的源码,理解其背后的实现机制。 首先,Spring事务管理有两种主要模式:编程式事务管理和声明式事务管理。编程式事务管理通过调用`PlatformTransactionManager`接口提供的方法进行显式...
通过对Spring Framework 5.3.4源码的深入学习,开发者不仅可以提升自己的技术能力,还能了解到更多设计原则和最佳实践。这将有助于在实际项目中编写出更高效、可维护的代码,同时也能更好地参与到Spring社区的发展中...
压缩包中的"spring-5.2.6.RELEASE-docs.zip"包含了完整的API文档和用户指南,是学习和理解Spring源码的重要参考资料。"spring-5.2.6.RELEASE-schema.zip"则包含框架使用的XML schema定义,帮助开发者理解和编写配置...
在深入探讨Spring框架的核心组件和工作原理时,我们经常会遇到需要构建或运行Spring源码的情况。Spring-cglib-repack-3.2.6.jar和spring-objenesis-repack-2.6.jar是两个至关重要的依赖库,它们在Spring框架的内部...
深入理解Spring源码,可以更好地掌握其设计理念和实现机制。2.5.6版本的源码包含了Spring的主要模块,如Core Container、Data Access/Integration、AOP、Web等。通过对这些模块的分析,我们可以了解到: - 如何通过...
通过阅读和学习这些源码,开发者可以了解到Spring如何实现IoC容器、AOP代理、事件机制、任务调度等多个关键功能。同时,这也有助于开发者更好地理解和使用Spring提供的API,以及在实际项目中如何定制和扩展Spring。 ...
根据提供的文件信息,本次解读将围绕Spring框架的核心概念与源码分析进行展开。Spring框架作为Java企业级开发中不可或缺的一部分,其源码的学习对于深入...希望以上内容能够为大家学习Spring源码提供一定的参考和帮助。
《深入剖析Spring Framework 5.3.4源码》 Spring Framework是Java开发中的核心框架,它为构建高质量、可维护的应用程序提供了全面的支持。在本文中,我们将深入探讨Spring Framework 5.3.4的源码,了解其设计理念、...