详细分析了Spring事务管理的源码,包括7种传播特性在存在事务和不存在事务情况下的处理逻辑,顺带着也把AOP的核心源码也一起分析了。
@EnableTransactionManagement注解分析
事务代理对象的创建AOP代理对象的创建类似,要启动事务管理,需要在配置类上使用@EnableTransactionManagement注解,来看看这个注解做了些什么事情:
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
//代理对象是否使用CGLIB来创建
boolean proxyTargetClass() default false;
//默认使用代理模式
AdviceMode mode() default AdviceMode.PROXY;
//默认最低优先级(拦截链上最后执行)
int order() default Ordered.LOWEST_PRECEDENCE;
}
看看 TransactionManagementConfigurationSelector 这个注册了些什么:
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
//默认PROXY, 导入AutoProxyRegistrar 和 ProxyTransactionManagementConfiguration 。
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
//ASPECTJ的方式会加载 AspectJTransactionManagementConfiguration
case ASPECTJ:
return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
default:
return null;
}
}
AutoProxyRegistrar 会往容器中注册 InfrastructureAdvisorAutoProxyCreator:
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean candidateFound = false;
Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
...
//注册 InfrastructureAdvisorAutoProxyCreator 。
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
...
}
这儿注意一点的是,如果我们同时使用@EnableAspectJAutoProxy这个的话,上一篇文章解析过,它会注册 AnnotationAwareAspectJAutoProxyCreator 这个类型AutoProxyCreator,此时spring会选择一个来注册,具体为AopConfigUtils.registerOrEscalateApcAsRequired 方法:
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
@Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//如果已经存在AutoProxyCreator,并且再次注册的class和已经注册的不一致,那么更具优先级进行替换(新注册的优先级高的话,就替换,否则不动)
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;
}
//注册具体的 AutoProxyCreator 。
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;
}
不通过类型的优先级定义:
static {
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}
简言之,如果@EnableAspectJAutoProxy启用的话,AutoProxyRegistrar其实没做啥子事情。
另外一个ProxyTransactionManagementConfiguration,是一个配置类,它主要会配置TransactionAttributeSource 、 TransactionInterceptor、 BeanFactoryTransactionAttributeSourceAdvisor:
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
//注入TransactionAttributeSource
advisor.setTransactionAttributeSource(transactionAttributeSource());
//注入TransactionInterceptor
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
//注入TransactionAttributeSource
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
事务代理对象的创建
@EnableTransactionManagement注解会注册 InfrastructureAdvisorAutoProxyCreator 或者使用 @EnableAspectJAutoProxy 的 AnnotationAwareAspectJAutoProxyCreator,无论使用哪一个,他们都继承至AbstractAutoProxyCreator(封装了核心逻辑),都是 InstantiationAwareBeanPostProcessor ,因此在getBean过程中,会触发 AbstractAutoProxyCreator.postProcessBeforeInstantiation 方法,这个方法在上一篇文章已经分析过了,对于我们事务来将,关键一步是
public List<Advisor> findAdvisorBeans() {
//找到容器中所有的Advisor类型,并将名称缓存到cachedAdvisorBeanNames
//这就会把前面配置中声明的BeanFactoryTransactionAttributeSourceAdvisor找到了。
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
//没有找到返回空列表
if (advisorNames.length == 0) {
return new ArrayList<>();
}
//有的话,getBean,然后加入到列表中返回。
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
...
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
...
}
}
}
return advisors;
}
同样,在AbstractAutoProxyCreator.postProcessAfterInitialization 方法中创建代理对象:
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
//如果有必要的话,包装成代理对象
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary的具体逻辑:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//一些前置校验
....
//找到适合当前bean的Advisor
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果有当前bean需要增强,则创建代理对象。
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理对象,具体的创建过程Aop源码分析中已经解析过了。
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;
}
代理对象的创建过程在前面AOP源码中已经分析过了,因此重点来看看针对事务的Advisor过程:
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//找到适合当前bean的advisor
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
//如果为空,没找到,返回DO_NOT_PROXY(null,即不需要代理)
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
findEligibleAdvisors方法:
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//找到所有候选的Advisor。这一步前面已经分析过了,会找到容器中所有的Advisor,这里面就包括了事务的 BeanFactoryTransactionAttributeSourceAdvisor
List<Advisor> candid