前两天被这个问题纠结了好久
如上,没有加@EnableAspectJAutoProxy注解的情况下,也是能正常完成事务管理的,并没有影响。网上也找不到合理的解释,都是说必须开启aop。
后来看源码发现了区别:
@EnableTransactionManagement和@EnableAspectJAutoProxy在Spring进行初始化的时候,分别会在BeanDefinitionMap中注册不同的BeanPostProcessor。
@EnableTransactionManagement注册的是InfrastructureAdvisorAutoProxyCreator,而@EnableAspectJAutoProxy注册的是AnnotationAwareAspectJAutoProxyCreator。
关键在AopConfigUtils.java中的判断:
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable 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;
}
当@EnableTransactionManagement开启事务管理时,会在一个新的BeanDefinition,beanName为org.springframework.aop.config.internalAutoProxyCreator,Class为org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator。
当加上@EnableAspectJAutoProxy时,会判断这个BeanDefinition是否存在,然后判断初始化进去的三个BeanPostProcessor的优先级,然后进行替换,如下:
所以如果开启支持AspectJ注解@EnableAspectJAutoProxy,到了最后就会剩下AnnotationAwareAspectJAutoProxyCreator。
结论就是,对结果没影响,只是因为使用的BeanPostProcessor不同,优先级越高,功能越强大。