承接上文,<tx:annotation-driven />开启声明式事务时,在SpringIOC容器中初始化了4个Bean
<!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 启用声明式事务管理 支持注解@Transaction-->
<tx:annotation-driven proxy-target-class="false" transaction-manager="transactionManager"/>
TransactionalEventListenerFactory AnnotationTransactionAttributeSource TransactionInterceptor//SpringAOP方法执行时的责任链拦截器 BeanFactoryTransactionAttributeSourceAdvisor//直接用bean创建的Advisor
由于前面没有具体深入了解每个Bean的作用以及实现,所以面试被难住了,补充一下Spring事务的具体实现。弄清楚三点:
- 每个组件的作用
- 事务的实现流程
- 与Mybatis的对接实现
一、组件初始化
/* org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser#registerTransactionalEventListenerFactory */
private void registerTransactionalEventListenerFactory(ParserContext parserContext) {
//创建TransactionEvenListenerFactory的Beandefinition
RootBeanDefinition def = new RootBeanDefinition();
def.setBeanClass(TransactionalEventListenerFactory.class);
parserContext.registerBeanComponent(new BeanComponentDefinition(def,
TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME));
}
/* org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer#configureAutoProxyCreator */
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
//若未注册,先注册SpringAOP相关Beandefinition
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
Object eleSource = parserContext.extractSource(element);
//Source的Beandefinition
//beanName = org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0
RootBeanDefinition sourceDef = new RootBeanDefinition(
"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
//实际eleSource == null
sourceDef.setSource(eleSource);
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//sourceName == org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
//Inteceptor的BeanDefinition
//beanName=org.springframework.transaction.interceptor.TransactionInterceptor#0
RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
interceptorDef.setSource(eleSource);
interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//初始化时的重要信息,设置TransactionInterceptor的属性trancationManagerBeanName的beanName,初始化时依赖注入
//实际获取<tx:annotation-driven transaction-manager="" >中的transaction-manage属性,默认值:beanName = transactionManager
registerTransactionManager(element, interceptorDef);
//TransactionInterception.trancationAttributeSource = AnnotationTransactionAttributeSource
interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
//interceptorName = org.springframework.transaction.interceptor.TransactionInterceptor#0
String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
//advisor的BeanDefinition
//beanName = org.springframework.transaction.config.internalTransactionAdvisor
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
advisorDef.setSource(eleSource);
advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//设置两个属性
//advisor.transactionAttributeSource = AnnotationTransactionAttributeSource的beanName
//advisor.adviceBeanName = TransactionInterceptor的beanName
advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
if (element.hasAttribute("order")) {
advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
}
//将组件的BeanDefinition注册到DefaultListableBeanFactory中
parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
parserContext.registerComponent(compositeDef);
}
}
总结下组件的依赖关系:
//Inteceptor TransactionInterceptor.trancationManagerBeanName = "transactionManager" TransactionInterceptor.transactionAttributeSource = AnnotationTransactionAttributeSource //advisor advisor.transactionAttributeSource = AnnotationTransactionAttributeSource advisor.advice = TransactionInterceptor
二、事务的AOP实现
SpringAOP实现流程:
① <aop:aspectj-autoproxy />开启SpringAOP代理支持后,会初始化AOP相关组件AnnotationAwareAspectJAutoProxyCreator
② 所有的Bean在初始化的最后阶段都会调用AnnotationAwareAspectJAutoProxyCreator.postprocessAfterInitialzation,判断是否需要生成代理类
③ List<Advisor> candidateAdvisors = findCandidateAdvisors();查找所有Advisor,
④ List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);Bean是否是切面关注点的判断,从所有advisor保留对应的advisor,
⑤ advisor不为空则会创建代理实例proxy object,为空不创建代理,直接返回原实例 target object
⑥ 创建一个ProxyFactory实例记录advisor,将ProxyFactory放入到InvocationHandler实例(jdk动态代理对应JdkDynamicAopProxy)中
⑦ 方法调用时,通过动态代理实现,调用代理类的方法,实际是调用InvocationHandler.invoke()方法(jdk动态代理对应JDKDynamicAopProxy.invoke)
⑧ invocationHandler.invoke具体是实现是:从proxyFactory中找到对应的advisor,然后调用advisor.getAdvice获取具体的advice操作侯然先执行advice后执行target object的方法
事务的实现流程是基于SpringAOP实现的。
1、@Transactional注解扫描,
对应流程③查找所有的advisor,会找到BeanFactoryTransactionAttributeSourceAdvisor
对应流程④Bean是否是切面关注点,根据BeanFactoryTransactionAttributeSourceAdvisor中的Pointcut判断,实际判断是否被@Transaction注解修饰
/* org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor#getPointcut */
/*
* BeanFactoryTransactionAttributeSourceAdvisor中的pointCut初始化
*/
public Pointcut getPointcut() {
return this.pointcut;
}
//pointCut实际是一个TransactionAttributeSourcePointcut实例
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
protected TransactionAttributeSourcePointcut() {
setClassFilter(new TransactionAttributeSourceClassFilter());
}
private class TransactionAttributeSourceClassFilter implements ClassFilter {
//判断Bean是否是poincut的一个join point(切面关注点)
@Override
public boolean matches(Class<?> clazz) {
if (TransactionalProxy.class.isAssignableFrom(clazz) ||
PlatformTransactionManager.class.isAssignableFrom(clazz) ||
PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
//三种基础类型直接返回false
return false;
}
//这里tas就是上面设置的AnnotationTrancationAttributeSource
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.isCandidateClass(clazz));
}
}
AnnotationTrancationAttributeSource.isCandidateClass():
/* org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#isCandidateClass */
public boolean isCandidateClass(Class<?> targetClass) {
for (TransactionAnnotationParser parser : this.annotationParsers) {
if (parser.isCandidateClass(targetClass)) {
return true;
}
}
return false;
}
//annotationParsers初始化
//annotationParsers.add(new SpringTransactionAnnotationParser())
//系统支持jta12时annotationParsers.add(new SpringTransactionAnnotationParser())
//系统支持ejb3时this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
if (jta12Present || ejb3Present) {
this.annotationParsers = new LinkedHashSet<>(4);
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
}
else {
this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());
}
}
//默认的SpringTransactionAnnotationParse.isCandidateClass
//判断类中包含@Transactional注解,
public boolean isCandidateClass(Class<?> targetClass) {
return AnnotationUtils.isCandidateClass(targetClass, Transactional.class);
}
对应流程⑤ 被@Transactional注解修饰的类的Bean,advisor = BeanFactoryTransactionAttributeSourceAdvisor,不为空创建代理实例
对应流程⑥ 将advisor放入到创建ProxFactory实例的advisors容器中
对应流程⑦ ⑧方法调用时获取BeanFactoryTransactionAttributeSourceAdvisor.getAdvice(),先执行advice.invoke,再执行target object.invoke。即开启事务执行sql提交(失败回退)。这里BeanFactoryTransactionAttributeSourceAdvisor.getAdvice()=TransactionInterceptor
TransactionInterceptor.invoke()
/* org.springframework.transaction.interceptor.TransactionInterceptor#invoke */
public Object invoke(MethodInvocation invocation) throws Throwable {
// target object可能为null,所以这里获取targetClass
//如果存在targetObject时 targetClass = targetObject.getClass
//如果不存在targetObject时 targetClass = null
//注意了mybatis接口绑定技术是没有targetObject的,这里targetClass == null
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// 事务执行
// 第三个参数lamda表达式:invocation.proceed()
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
TransactionAspectSupport.invokeWithinTransaction()
来源:https://www.cnblogs.com/wqff-biubiu/p/12540147.html