本文基于
Springboot 2.1.0JPA应用分析总结。
- 应用启动过程中
Spring AOP自动配置机制AopAutoConfiguration执行仅在注解
@EnableAspectJAutoProxy类存在于classpath并且spring.aop没有明确设置为false时应用
可以认为等价于主动使用注解@EnableAspectJAutoProxy- 注解
@EnableAspectJAutoProxy导入了类AspectJAutoProxyRegistrarAspectJAutoProxyRegistrar是一个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:AnnotationTransactionAttributeSourceAnnotationTransactionAttributeSource用于分析理解事务注解属性@Transactional的语义ProxyTransactionManagementConfiguration配置类定义bean:TransactionInterceptor属性
transactionAttributeSource:bean AnnotationTransactionAttributeSourceProxyTransactionManagementConfiguration配置类定义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; } - 因为

173万+





