一、使用
先说下使用,在SpringBoot启动类上加注解,表示开启声明式事务
@EnableTransactionManagement
然后在Service方法上加
@Transactional
二、实现逻辑
看下注解EnableTransactionManagement的源码
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
}
看下@Import导入的类TransactionManagementConfigurationSelector
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
default:
return null;
}
}
小结:其原理是通过@Import导入TransactionManagementConfigurationSelector组件,然后又通过TransactionManagementConfigurationSelector导入组件AutoProxyRegistrar和ProxyTransactionManagementConfiguration;
三、AutoProxyRegistrar
AutoProxyRegistrar会注册:InfrastructureAdvisorAutoProxyCreator
name = org.springframework.aop.config.internalAutoProxyCreator
AutoProxyRegistrar继承了几个重要的类
1、SmartInstantiationAwareBeanPostProcessor 2、InstantiationAwareBeanPostProcessor 3、BeanPostProcessor
这里就很AOP的AnnotationAwareAspectJAutoProxyCreator很类似了,父类都有SmartInstantiationAwareBeanPostProcessor
疑问 1、启动前InfrastructureAdvisorAutoProxyCreator会做哪些事?
四、ProxyTransactionManagementConfiguration
ProxyTransactionManagementConfiguration是一个配置类,会向IOC容器中导入
1、事务增强器(BeanFactoryTransactionAttributeSourceAdvisor)。简称:事务增强器(Advisor) 2、事务注解@Transactional的解析器(AnnotationTransactionAttributeSource) 。简称:@Transactional注解的解析类 3、事务方法拦截器(TransactionInterceptor)。简称:事务方法的拦截器
也就是下面三个bean
@Configuration
ProxyTransactionManagementConfiguration{
1、@Bean BeanFactoryTransactionAttributeSourceAdvisor
2、@Bean AnnotationTransactionAttributeSource
3、@Bean TransactionInterceptor
}
看下具体的代码:
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource());
advisor.setAdvice(transactionInterceptor());
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();
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
1、“事务增强器”创建需要 “事务注解解析器”和“事务方法拦截器” 2、“事务方法拦截器”创建依赖“事务注解解析器”, 3、“事务注解解析器”是独立创建
其中定义的事务增强器:BeanFactoryTransactionAttributeSourceAdvisor
name = org.springframework.transaction.config.internalTransactionAdvisor
1、事务增强器BeanFactoryTransactionAttributeSourceAdvisor
里面有个属性TransactionAttributeSourcePointcut,它有个方法matches,该类会通过 “@Transaction事务方法解析器” ,来匹配目标方法是否带有事务注解,当然判断事务注解有很多种
@Override
public boolean matches(Method method, Class<?> targetClass) {
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
2、@Transaction注解解析器AnnotationTransactionAttributeSource
调用SpringTransactionAnnotationParser类来处理@Transaction注解
3、事务方法拦截器TransactionInterceptor
功能
TransactionInterceptor,实现了MethodInterceptor接口,主要用于拦截事务方法的执行
先说下执行流程,当请求进来的时候,会执行JdkDynamicAopProxy的invoke方法,这时会拿到方法的拦截器链,下面是获取目标方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
然后执行拦截器链中的最开始的拦截器,后面一次遍历,但是此时的拦截器就只有一个就是TransactionInterceptor事务方法拦截器
进到TransactionInterceptor就会执行TransactionInterceptor的invoke方法,下面看下invoke的流程
1、先拿到事务管理器的事务类型:PROPAGATION_REQUIRED,ISOLATION_DEFAULT; 2、在拿到事务的管理器也就是DataSourceTransactionManager
@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
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);
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
try {
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
commitTransactionAfterReturning(txInfo);
return retVal;
}
五、疑问
1、带有@Transaction注解的Bean实例化的时候,怎么如果判断该Bean带有@Transaction方法
1、InfrastructureAdvisorAutoProxyCreator#postProcessAfterInitialization —>2、BeanFactoryTransactionAttributeSourceAdvisor —>3、AnnotationTransactionAttributeSource —>4、SpringTransactionAnnotationParser判断@Transaction
最终通过SpringTransactionAnnotationParser来判断Bean的方法是否带有@Transaction注解
拓展: InfrastructureAdvisorAutoProxyCreator里面有个advisedBeans属性,在Bean的创建过程会判断Bean里面 是否是带有事务注解@Transaction的方法,如果有就会被加到advisedBeans里面去。
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<Object, Boolean>(256);
注意: 1、BeanFactoryTransactionAttributeSourceAdvisor事务增强器在advisedBeans是false的形式存在 2、transactionInterceptor也是false
2、带有@Transaction注解的代理Bean在哪个流程被创建
在执行BeanPostProcess处理器链的时候,由InfrastructureAdvisorAutoProxyCreator#postProcessAfterInitialization方法执行创建,该方法会调用wrapIfNecessary方法完成代理创建
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);
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
return proxy;
}
return bean;
}
3、如何创建@Transaction注解的Bean 默认是使用JDK动态代理
1、先创建ProxyFactory对象,设置属性
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTargetSource(目标对象LLServcieImpl);
proxyFactory.setInterfaces(目标接口LLServcie);
proxyFactory.addAdvisor(事务增强器BeanFactoryTransactionAttributeSourceAdvisor);
proxyFactory.getProxy(getProxyClassLoader())
proxiedInterfaces=AopProxyUtils.completeProxiedInterfaces(事务增强器, true);
Proxy.newProxyInstance(classLoader, proxiedInterfaces, JdkDynamicAopProxy类);
其中proxiedInterfaces包含接口
0 = {Class@3511} “interface cn.tedu.sample2.util.LLServcie” 1 = {Class@3676} “interface org.springframework.aop.SpringProxy” 2 = {Class@5780} “interface org.springframework.aop.framework.Advised” 3 = {Class@3897} “interface org.springframework.core.DecoratingProxy”
4、InfrastructureAdvisorAutoProxyCreator类的作用
1、postProcessBeforeInstantiation方法主要是针对所有要创建的Bean,判断存到advisedBeans里面是false还是true 2、postProcessAfterInitialization方法,处理带有@Transcation的Bean,创建代理Bean
六、总结
1、先通过@EnableTransactionManagement引入TransactionManagementConfigurationSelector 2、通过TransactionManagementConfigurationSelector,导入AutoProxyRegistrar,ProxyTransactionManagementConfiguration 3、AutoProxyRegistrar会向容器中注册InfrastructureAdvisorAutoProxyCreator 4、ProxyTransactionManagementConfiguration会向容器定义三个Bean:事务增强器、@Transaction注解解析器、事务方法拦截器 5、执行Bean的后置处理器时,通过InfrastructureAdvisorAutoProxyCreator的postProcessAfterInitialization方法创建代理对象 6、创建代理对象时,通过事务增强器BeanFactoryTransactionAttributeSourceAdvisor来得到代理类要实现的接口SpringProxy、Advised、DecoratingProxy,最终生成代理对象
7、当请求进来时,先进入JdkDynamicAopProxy的invoke方法 8、invoke里面会调用TransactionInterceptor的invoke方法,里面会调用invokeWithinTransaction方法 9、invokeWithinTransaction里面会在调用目标方法前开启事务,catch失败设置状态,然后finally根据状态来确认是否commit
|