Spring何时为使用事务注解的bean创建代理 ?
本文基于
Springboot 2.1.0
JPA
应用分析总结。
- 应用启动过程中
Spring AOP
自动配置机制AopAutoConfiguration
执行仅在注解
@EnableAspectJAutoProxy
类存在于classpath
并且spring.aop
没有明确设置为false
时应用
可以认为等价于主动使用注解@EnableAspectJAutoProxy
- 注解
@EnableAspectJAutoProxy
导入了类AspectJAutoProxyRegistrar
AspectJAutoProxyRegistrar
是一个ImportBeanDefinitionRegistrar
, -
AspectJAutoProxyRegistrar
向容器注册一个AnnotationAwareAspectJAutoProxyCreator
,长类名 :
org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
这是一个BeanPostProcessor
,它会在每个bean
实例创建时检查该bean
是否需要创建代理,需要的话
就创建相应的代理。
- 注解
- 应用启动过程中自动配置机制
TransactionAutoConfiguration
执行TransactionAutoConfiguration
使用了注解@EnableTransactionManagement
- 注解
@EnableTransactionManagement
导入TransactionManagementConfigurationSelector
-
TransactionManagementConfigurationSelector
根据参数和包引用状态决定引入 :-
ProxyTransactionManagementConfiguration
(PROXY
)或者 -
AspectJJtaTransactionManagementConfiguration
(ASPECTJ
,使用JTA
) 或者 -
AspectJTransactionManagementConfiguration
(ASPECTJ
,不使用JTA
)
ProxyTransactionManagementConfiguration
是较常见的一种情况,这里我们以此为例继续分析。 -
-
ProxyTransactionManagementConfiguration
配置类定义bean
:AnnotationTransactionAttributeSource
AnnotationTransactionAttributeSource
用于分析理解事务注解属性@Transactional
的语义 -
ProxyTransactionManagementConfiguration
配置类定义bean
:TransactionInterceptor
属性
transactionAttributeSource
:bean AnnotationTransactionAttributeSource
-
ProxyTransactionManagementConfiguration
配置类定义bean
:BeanFactoryTransactionAttributeSourceAdvisor
类型 :
BeanFactoryTransactionAttributeSourceAdvisor
, 名称:transactionAdvisor
属性advice
:bean TransactionInterceptor
属性transactionAttributeSource
:bean AnnotationTransactionAttributeSource
- 注解
- 某个带有事务注解属性的服务组件
bean
(带注解@Component
)首次被使用时实例化- 因为
AnnotationAwareAspectJAutoProxyCreator
是一个BeanPostProcessor
,所以它在每个bean
实例化时会针对该bean
执行,所以在带有事务注解属性的服务组件bean
被实例化时,它也被应用; - 服务组件
bean
如果在类或者方法级别使用了事务注解@Transactional
,则它会被AnnotationAwareAspectJAutoProxyCreator
认为是需要创建代理(用于进行事务处理),否则不需要创建代理 ; -
AnnotationAwareAspectJAutoProxyCreator
认为某个服务组件bean
需要创建代理对象时,为其创建代理。
具体代码参考AnnotationAwareAspectJAutoProxyCreator
基类AbstractAutoProxyCreator
:
// AnnotationAwareAspectJAutoProxyCreator 基类 AbstractAutoProxyCreator 代码片段 // 接口 BeanPostProcessor 定义的方法 @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. // 使用了事务注解的bean上的事务注解@Transactional会被发现, // 进而发现 bean BeanFactoryTransactionAttributeSourceAdvisor 到 specificInterceptors // 具体的发现逻辑可以参考工具类方法 : AopUtils#findAdvisorsThatCanApply Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); // 如果 specificInterceptors 不为空,说明需要有 advise 需要被应用到该bean,所以需要创建相应的代理 // 对象,外面包裹相应的 advise : specificInterceptors 。 // 这里 DO_NOT_PROXY 是一个常量,值为 null if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 创建代理 // 原bean对象 : bean // 代理对象 : proxy Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
- 因为
相关文章
- Spring Transaction 5.1.2 源代码分析 : AnnotationTransactionAttributeSource 解析注解式事务属性
- Spring BeanPostProcessor : AnnotationAwareAspectJAutoProxyCreator
本文地址:https://blog.csdn.net/andy_zhang2007/article/details/85949880
上一篇: Java IO.File类的删除功能
下一篇: XMLHTTP下载远程数据输出到浏览器