Spring 事务剖析
点击上方☝SpringForAll社区 轻松关注!
本文来源:http://x7j.net/buh5w
注册后置处理器开启对事务的支持
@EnableTransactionManagement
@EnableTransactionManagement
注解的主要作用是开启对事务的支持,源码如下:
@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 后置处理器和事务管理器组件
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
后置处理器一样,这里就不在重复说明了。InfrastructureAdvisorAutoProxyCreator 他是实现了BeanPostProcessor 接口的后置处理器,所以所有 Bean 的初始化都会调用其 postProcessAfterInitialization
方法,这个方法的实现是在其父类AbstractAutoProxyCreator类中。
ProxyTransactionManagementConfiguration
我们通过ProxyTransactionManagementConfiguration
来注册事务管理器组件,这个类本身也是一个配置类。在这个配置类中我们将会注册一下三个组件:
BeanFactoryTransactionAttributeSourceAdvisor:事务增强器,包含了切面组件 TransactionInterceptor
和标签解析器TransactionAttributeSource
TransactionAttributeSource:@Transaction注解标签解析器 TransactionInterceptor:保存了事务属性信息,事务管理器;它本身也是一个方法拦截器,在invoke方法中进行了事务的处理。
创建代理Bean
上面我们说了所以所有 Bean 的初始化都会调用其 AbstractAutoProxyCreator#postProcessAfterInitialization
方法来完成Bean的增强,我们跟进去可以看到这段代码:
@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) {
// 如果存在建言那么久创建代理类
// 获取拦截链
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 使用拦截链创建代理对象,对原有的Bean进行增强
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) {
// 获取所有增强器的名称
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 {
// 根据名称增强器
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
...
}
}
}
// 返回拦截链
return advisors;
}
创建代理Bean的核心流程:
单例Bean初始化完成后执行后置处理器 AbstractAutoProxyCreator#postProcessAfterInitialization
方法在容器中找 Advisor
类型的所有增强器名称,这就会将与事务相关的增强器BeanFactoryTransactionAttributeSourceAdvisor
找出来根据增强器名称获取对应的实例,并生成拦截链 判断代理类型 根据不同的代理类型和拦截链创建代理对象
执行业务方法进行拦截
前面AOP说过不管理是JdkDynamicAopProxy
还是CglibAopProxy
代理,他们的执行最终都会去调用MethodInterceptor.invoke()
方法,而我们事务对应的方法拦截器是TransactionInterceptor
类。也就是说我们对事务的增强起始是在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 {
// 获取事务属性
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
// 获取事务管理器
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
// 构造方法唯一标示
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// 声明式事务
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// 创建事务
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// 执行被增强的方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 异常回滚
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
// 清除信息
cleanupTransactionInfo(txInfo);
}
// 提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
// 编程式事务
...
}
从上面我们的源码可以看出,一个事务处理的标准流程:
createTransactionIfNecessary
创建一个事务invocation.proceedWithInvocation();
执行业务方法completeTransactionAfterThrowing(txInfo, ex);
如果遇到异常,事务回滚commitTransactionAfterReturning(txInfo);
如果没有异常就提交事务
在创建,回滚和提交事务方法中还有的很多对嵌套事务的逻辑,比如事务的传递性,事务回滚的条件判断等,这里就不说了,有兴趣自己去跟下源码。
墙裂推荐
【深度】互联网技术人的社群,点击了解!
关注公众号,回复“spring”有惊喜!!!
如果资源对你有帮助的话