注冊后置處理器開啟對事務(wù)的支持
@EnableTransactionManagement
@EnableTransactionManagement
注解的主要作用是開啟對事務(wù)的支持啼辣,源碼如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}
這里最核心的是TransactionManagementConfigurationSelector類,這個類主要的作用是通過ImportSelector
注冊了AutoProxyRegistrar
和ProxyTransactionManagementConfiguration
2個組件御滩,源碼如下:
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
// 注冊 InfrastructureAdvisorAutoProxyCreator 后置處理器和事務(wù)管理器組件
return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
default:
return null;
}
}
}
AutoProxyRegistrar
AutoProxyRegistrar 的主要作用是將InfrastructureAdvisorAutoProxyCreator
后置處理器注冊到容器鸥拧,注冊這個后置處理器和上一篇Spring AOP注冊AnnotationAwareAspectJAutoProxyCreator
后置處理器一樣,這里就不在重復(fù)說明了削解。InfrastructureAdvisorAutoProxyCreator 他是實現(xiàn)了BeanPostProcessor 接口的后置處理器富弦,所以所有 Bean 的初始化都會調(diào)用其 postProcessAfterInitialization
方法,這個方法的實現(xiàn)是在其父類AbstractAutoProxyCreator類中氛驮。
ProxyTransactionManagementConfiguration
我們通過ProxyTransactionManagementConfiguration
來注冊事務(wù)管理器組件舆声,這個類本身也是一個配置類。在這個配置類中我們將會注冊一下三個組件:
- BeanFactoryTransactionAttributeSourceAdvisor:事務(wù)增強(qiáng)器柳爽,包含了切面組件
TransactionInterceptor
和標(biāo)簽解析器TransactionAttributeSource
- TransactionAttributeSource:@Transaction注解標(biāo)簽解析器
- TransactionInterceptor:保存了事務(wù)屬性信息媳握,事務(wù)管理器;它本身也是一個方法攔截器磷脯,在invoke方法中進(jìn)行了事務(wù)的處理蛾找。
創(chuàng)建代理Bean
上面我們說了所以所有 Bean 的初始化都會調(diào)用其 AbstractAutoProxyCreator#postProcessAfterInitialization
方法來完成Bean的增強(qiáng),我們跟進(jìn)去可以看到這段代碼:
@Override
public Object postProcessAfterInitialization(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(bean, beanName, cacheKey);
方法中完成的赵誓,源碼如下:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果存在建言那么久創(chuàng)建代理類
// 獲取攔截鏈
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 使用攔截鏈創(chuàng)建代理對象打毛,對原有的Bean進(jìn)行增強(qiáng)
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;
}
找到攔截鏈的的核心方法是 BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans
方法
findAdvisorBeans:67, BeanFactoryAdvisorRetrievalHelper (org.springframework.aop.framework.autoproxy)
findCandidateAdvisors:102, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
findEligibleAdvisors:88, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
getAdvicesAndAdvisorsForBean:70, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
wrapIfNecessary:346, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
postProcessAfterInitialization:298, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsAfterInitialization:423, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1638, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:555, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:483, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:312, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:308, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:761, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:867, AbstractApplicationContext (org.springframework.context.support)
refresh:543, AbstractApplicationContext (org.springframework.context.support)
<init>:84, AnnotationConfigApplicationContext (org.springframework.context.annotation)
源碼如下:
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = null;
synchronized (this) {
advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// 獲取所有增強(qiáng)器的名稱
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
}
if (advisorNames.length == 0) {
return new LinkedList<Advisor>();
}
List<Advisor> advisors = new LinkedList<Advisor>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
// 根據(jù)名稱增強(qiáng)器
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
...
}
}
}
// 返回攔截鏈
return advisors;
}
創(chuàng)建代理Bean的核心流程:
- 單例Bean初始化完成后執(zhí)行后置處理器
AbstractAutoProxyCreator#postProcessAfterInitialization
方法- 在容器中找
Advisor
類型的所有增強(qiáng)器名稱柿赊,這就會將與事務(wù)相關(guān)的增強(qiáng)器BeanFactoryTransactionAttributeSourceAdvisor
找出來- 根據(jù)增強(qiáng)器名稱獲取對應(yīng)的實例,并生成攔截鏈
- 判斷代理類型
- 根據(jù)不同的代理類型和攔截鏈創(chuàng)建代理對象
執(zhí)行業(yè)務(wù)方法進(jìn)行攔截
前面AOP說過不管理是JdkDynamicAopProxy
還是CglibAopProxy
代理幻枉,他們的執(zhí)行最終都會去調(diào)用MethodInterceptor.invoke()
方法碰声,而我們事務(wù)對應(yīng)的方法攔截器是TransactionInterceptor
類。也就是說我們對事務(wù)的增強(qiáng)起始是在TransactionInterceptor
的invoke
方法中熬甫。源碼如下:
@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
...
return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
@Override
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
});
}
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
throws Throwable {
// 獲取事務(wù)屬性
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
// 獲取事務(wù)管理器
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
// 構(gòu)造方法唯一標(biāo)示
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// 聲明式事務(wù)
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// 創(chuàng)建事務(wù)
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// 執(zhí)行被增強(qiáng)的方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 異骋忍簦回滾
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
// 清除信息
cleanupTransactionInfo(txInfo);
}
// 提交事務(wù)
commitTransactionAfterReturning(txInfo);
return retVal;
}
// 編程式事務(wù)
...
}
從上面我們的源碼可以看出,一個事務(wù)處理的標(biāo)準(zhǔn)流程:
-
createTransactionIfNecessary
創(chuàng)建一個事務(wù) -
invocation.proceedWithInvocation();
執(zhí)行業(yè)務(wù)方法 -
completeTransactionAfterThrowing(txInfo, ex);
如果遇到異常椿肩,事務(wù)回滾 -
commitTransactionAfterReturning(txInfo);
如果沒有異常就提交事務(wù)
在創(chuàng)建瞻颂,回滾和提交事務(wù)方法中還有的很多對嵌套事務(wù)的邏輯,比如事務(wù)的傳遞性郑象,事務(wù)回滾的條件判斷等贡这,這里就不說了,有興趣自己去跟下源碼厂榛。