highlight: arduino-light
整体流程
第一步是注入自定义的事务管理器。
第二步是注入事务相关组件。
0.注入PlatformTransactionManager
//默认的bean名称是 myPlatformTransactionManager
@Component()
public class MyPlatformTransactionManager implements PlatformTransactionManager {
@Override
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
System.out.println("getTransaction");
return new SimpleTransactionStatus();
}
@Override
public void commit(TransactionStatus status) throws TransactionException {
System.out.println("commit");
}
@Override
public void rollback(TransactionStatus status) throws TransactionException {
System.out.println("rollback");
}
}
1.注入InfrastructureAdvisorAutoProxyCreator
主要的作用有2个:
1.参与获取候选advisor
在获取候选advisor时,让我们可以获取到BeanFactoryTransactionAttributeSourceAdvisor。
因为BeanFactoryTransactionAttributeSourceAdvisor的ROLE就是BeanDefinition.ROLE_INFRASTRUCTURE
InfrastructureAdvisorAutoProxyCreator获取候选ROLE的逻辑也是判断是否等于BeanDefinition.ROLE_INFRASTRUCTURE.
2.作为beanPostProcessor被注入,在生成代理对象时参与代理的过程!
@Override
protected boolean isEligibleAdvisorBean(String beanName) {
/****
这个条件是寻找AVISOR的Role是 ROLE_INFRASTRUCTURE
比如 BeanFactoryTransactionAttributeSourceAdvisor
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {}
*/
return (this.beanFactory != null &&
this.beanFactory
.containsBeanDefinition(beanName) &&
//判断getRole() == BeanDefinition.ROLE_INFRASTRUCTURE
this.beanFactory
.getBeanDefinition(beanName)
.getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
}
2.注入BeanFactoryTransactionAttributeSourceAdvisor
注入BeanFactoryTransactionAttributeSourceAdvisor对应的bean实例,让我们在生成代理获取候选的advisor时可以获取到这个advsior。
注入的advisor有以下属性
//注入解析器
//可以调用getTransactionAttributeSource 获取解析器
//解析方法上是否存在@Transaction注解
advisor.setTransactionAttributeSource(transactionAttributeSource());
//transactionInterceptor()返回1个transactionInterceptor
//transactionInterceptor里包含了事务管理器
//有2个用处:
//1.获取调用链时调用getInterceptorsAndDynamicInterceptionAdvice方法
//将BeanFactoryTransactionAttributeSourceAdvisor
//转换为transactionInterceptor
//因为在BeanFactoryTransactionAttributeSourceAdvisor的注入方法中已经设置了
//advisor.setAdvice(transactionInterceptor());
//2.执行代理类的invoke方法的时候会用上此处的transactionInterceptor中的事务管理器
//具体看transactionInteceptor的invoke方法
advisor.setAdvice(transactionInterceptor());
3.查找所有候选的Advisor
因为@Transactional的原理是基于AOP的,所以匹配TransactionInterceptor增强的逻辑,其实就是AOP匹配增强的地方。
Object[] specificInterceptors
= getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
大家可以看到,上边就是在创建AOP代理之前,为目标类匹配增强的入口,那么我们就从这里开始分析吧。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//先查找所有的候选Advisors
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//筛选所有的可应用的Advisors 就是解析表达式
//判断是否匹配 具体:解析表达式生成匹配器
//然后和所有的方法进行匹配只要满足就可以加入eligibleAdvisors
List<Advisor> eligibleAdvisors
= findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
//在指定下标位置插入一个元素 当前下标元素以后当前下标元素后面的元素往后移动
//advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
extendAdvisors(eligibleAdvisors);
//最后排序
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
我们知道,在匹配增强的时候,首先就是要找到所有的增强。
@Override
protected List<Advisor> findCandidateAdvisors() {
// 根据类型Advisor找
List<Advisor> advisors = super.findCandidateAdvisors();
// 解析@Aspect注解声明的增强 查找Advisor
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
看下@Aspect注解声明的增强是如何被查找到的
public List<Advisor> buildAspectJAdvisors() {
//获取所有带有@Aspect注解的类名
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
//获取所有的beanName
String[] beanNames
= BeanFactoryUtils
.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//遍历所有的beanName
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//判断是否有@Aspect注解
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind()
== PerClauseKind.SINGLETON) {
//构建解析Aspect的工厂类
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory
(this.beanFactory, beanName);
//解析Aspect下的所有的Advisor 并放入缓存中
List<Advisor> classAdvisors
= this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("");
}
MetadataAwareAspectInstanceFactory factory
= new PrototypeAspectInstanceFactory
(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
//遍历所有的Aspect
for (String aspectName : aspectNames) {
//根据AspectName从advisorsCache中获取对应的List<Advisor> 并加入advisors
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
//如果是AspectJAdvisorFactory接口类型的实现类
//直接调用getAdvisors 获取对应的List<Advisor> 加入 advisors
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
先看这一句
this.advisorFactory.getAdvisors(factory);
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
//获取所有的增强方法:1.非合成非桥接 2.不是@PointCut所在的方法
for (Method method : getAdvisorMethods(aspectClass)) {
//构建InstantiationModelAwarePointcutAdvisorImpl实例
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory
.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor
(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
final List<Method> methods = new ArrayList<>();
/***
aspectClass:@Aspect注解的类
*/
ReflectionUtils.doWithMethods(aspectClass, method -> {
// MethodCallback
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
},
//MethodFilter
ReflectionUtils.USER_DECLARED_METHODS);
if (methods.size() > 1) {
methods.sort(METHOD_COMPARATOR);
}
return methods;
}
public static void doWithMethods(Class<?> clazz, MethodCallback mc, @Nullable MethodFilter mf) {
// 获取所有声明的方法
Method[] methods = getDeclaredMethods(clazz);
//遍历方法
for (Method method : methods) {
//MethodFilter:非桥接 非合成
if (mf != null && !mf.matches(method)) {
continue;
}
try {
//MethodCallback:非@Point声明的方法
mc.doWith(method);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException();
}
}
//获取父类上的方法
if (clazz.getSuperclass() != null) {
doWithMethods(clazz.getSuperclass(), mc, mf);
}else if (clazz.isInterface()) {
//获取父接口
for (Class<?> superIfc : clazz.getInterfaces()) {
doWithMethods(superIfc, mc, mf);
}
}
}
接下来看这一句代码
getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//判断方法上是否存在增强注解
AspectJExpressionPointcut expressionPointcut
= getPointcut(candidateAdviceMethod,
aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//构建InstantiationModelAwarePointcutAdvisorImpl
return new InstantiationModelAwarePointcutAdvisorImpl
(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
//获取增强增强注解 因为Pointcut上面已经被过滤掉了 所以这里只会筛选剩下5种注解修饰的方法
//@Around,@Before,@After,@AfterReturning,@AfterThrowing
AspectJAnnotation<?> aspectJAnnotation
=AbstractAspectJAdvisorFactory
.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
//构建AspectJExpressionPointcut
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut
(candidateAspectClass, new String[0], new Class<?>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
if (this.beanFactory != null) {
ajexp.setBeanFactory(this.beanFactory);
}
//返回AspectJExpressionPointcut
return ajexp;
}
总结1下:获取的是非合成非桥接没有被@Pointcut修饰并且有注解增强的方法。
4.查找符合条件的Advisor
/***
1.遍历所有的Advisor其中包含BeanFactoryTransactionAttributeSourceAdvisor
2.获取Advisor的pointcut
BeanFactoryTransactionAttributeSourceAdvisor继承了AbstractBeanFactoryPointcutAdvisor
属于PointcutAdvisor
pointcutAdvisor.getPointcut()
返回的是 TransactionAttributeSource是1个解析器
3.遍历类的所有方法,调用Pointcut#match判断是否是合适的Advisor
TransactionAttributeSourcePointcut继承自StaticMethodMatcherPointcut
重写了match方法。
TransactionAttributeSource的match方法主要逻辑:
调用解析器查找方法是否存在@Transactional注解
如果方法上存在@Transactional注解!那么这个Advisor就是可以被使用的
***/
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//先查找所有的候选Advisors
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//筛选所有的可应用的Advisors 就是解析表达式 判断是否匹配
//具体:解析表达式生成匹配器
//然后和所有的方法进行匹配只要满足就可以加入eligibleAdvisors
List<Advisor> eligibleAdvisors
= findAdvisorsThatCanApply
(candidateAdvisors, beanClass, beanName);
//在指定下标位置插入一个元素 当前下标元素以后当前下标元素后面的元素往后移动
//advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
extendAdvisors(eligibleAdvisors);
//最后排序
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
接下来我们重点看这一行代码
List<Advisor> eligibleAdvisors
= findAdvisorsThatCanApply
(candidateAdvisors, beanClass, beanName);
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
//符合条件的Advisor
List<Advisor> eligibleAdvisors = new ArrayList<>();
//遍历所有的候选Advisor
for (Advisor candidate : candidateAdvisors) {
//判断是否是引介增强
if (candidate instanceof IntroductionAdvisor
&& canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
//因为没有引介增强 eligibleAdvisors是空 eligibleAdvisors.isEmpty()=true
//!eligibleAdvisors.isEmpty()=false
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
//遍历所有的Advisor其中包含BeanFactoryTransactionAttributeSourceAdvisor
for (Advisor candidate : candidateAdvisors) {
//引介增强上面处理过
if (candidate instanceof IntroductionAdvisor) {
continue;
}
//进入这里作为普通增强处理 hasIntroductions=false
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
public static boolean canApply(Advisor advisor,
Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor)
.getClassFilter().matches(targetClass);
//我们的advisor有2种
//aop:InstantiationModelAwarePointcutAdvisorImpl
//事务:BeanFactoryTransactionAttributeSourceAdvisor
//都是PointcutAdvisor
}else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
//对于aop来说
//pca.getPointcut()返回的是AspectJExpressionPointcut
//对于事务来说:
//pca.getPointcut() 返回的是StaticMethodMatcherPointcut
//TransactionAttributeSource又继承了StaticMethodMatcherPointcut
//重写了match方法
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
return true;
}
}
TransactionAttributeSource又继承了StaticMethodMatcherPointcut重写了match方法
public static boolean canApply(Pointcut pc,
Class<?> targetClass,boolean hasIntroductions) {
//先基于类级别进行过滤
//对于事务来说:根据源码版本不同有2种情况
//1.ClassFilter.TRUE; 永远返回的都是true
//2.TransactionAttributeSourceClassFilter;
//只要目标类既不是java自己的类,也不是Spring里的Ordered接口类型。那么目标类是满足类级别匹配的。
//对于aop来说:AspectJExpressionPointcut.getClassFilter就是AspectJExpressionPointcut
//匹配切面表达式和类是否匹配
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
//获取方法匹配器
//pca.getPointcut() 返回的是 TransactionAttributeSource是1个解析器
//TransactionAttributeSource又继承了StaticMethodMatcherPointcut
//重写了match方法
//目标方法或目标方法所在的类上有没有加@Transactional注解
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
return true;
}
//判断是否是IntroductionAwareMethodMatcher
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher =
(IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
//targetClass是我们的代理类 AopLog
if (!Proxy.isProxyClass(targetClass)) {
//targetClass = class transaction.AopLog
classes.add(ClassUtils.getUserClass(targetClass));
}
//获取代理类的所有接口
// ClassUtils.getAllInterfacesForClassAsSet(targetClass)
// 0 = {Class@2137} "interface transaction.LogService"
// 1 = {Class@2138} "interface transaction.PrintService"
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
//每一个advisor的匹配器和class的所有接口方法匹配
//只要advisor的匹配器和任何一个方法匹配 就把该方法加入eligible集合
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
//方法匹配器匹配的情况
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches
(method, targetClass, hasIntroductions) :
//重点看这里
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
//参数1:方法
@Override
public boolean matches(Method method, Class<?> targetClass) {
if (TransactionalProxy.class.isAssignableFrom(targetClass) ||
PlatformTransactionManager.class.isAssignableFrom(targetClass) ||
PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) {
return false;
}
/***
public AnnotationTransactionAttributeSource() {
//publicMethodsOnly=true
this(true);
}
***/
//注意获取的是AnnotationTransactionAttributeSource
TransactionAttributeSource tas = getTransactionAttributeSource();
//调用AnnotationTransactionAttributeSource#getTransactionAttribute
return (tas == null || tas.getTransactionAttribute
(method, targetClass) != null);
}
@Nullable
protected abstract TransactionAttributeSource getTransactionAttributeSource();
}
@Override
@Nullable
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
if (method.getDeclaringClass() == Object.class) {
return null;
}
Object cacheKey = getCacheKey(method, targetClass);
TransactionAttribute cached = this.attributeCache.get(cacheKey);
if (cached != null) {
if (cached == NULL_TRANSACTION_ATTRIBUTE) {
return null;
}
else {
return cached;
}
}
else {
//调用解析器查找类上或者方法上的@Transactional注解并返回
TransactionAttribute txAttr =
computeTransactionAttribute(method, targetClass);
// 如果没找到类上或者方法上的@Transactional注解 那么放到缓存里 下次不用再找了
if (txAttr == null) {
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
}else {
// 如果找到类上或者方法上的@Transactional注解 那么放到缓存里 下次不用再找了
String methodIdentification
= ClassUtils
.getQualifiedMethodName(method, targetClass);
if (txAttr instanceof DefaultTransactionAttribute) {
((DefaultTransactionAttribute) txAttr)
.setDescriptor(methodIdentification);
}
//放入缓存
this.attributeCache.put(cacheKey, txAttr);
}
//所以这里返回的是@Transactional注解上的属性
return txAttr;
}
}
先看下AnnotationTransactionAttributeSource#computeTransactionAttribute(method, targetClass);
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
//是否只允许public方法
//并且方法的声明是public才能生效
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
//在方法上找获取@Transactional上的属性
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
//在类上找获取@Transactional上的属性
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
if (specificMethod != method) {
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
protected boolean allowPublicMethodsOnly() {
return this.publicMethodsOnly;
}
publicMethodsOnly从哪来的呢?
```
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
/***
true代表是针对public方法 哈哈哈 这下知道为什么非public方法事务会失效了吧?
public AnnotationTransactionAttributeSource() {
this(true);
}
*/
return new AnnotationTransactionAttributeSource();
}
```
如果上边if语句中的布尔表达式满足的话,就会执行返回null,那么结合上节的文章,我们知道,如果这里返回null的话,那么就代表当前方法不支持事务,最重要的TransactionInterceptor增强就不会生效,由此看来,这个应该是在获取事务属性之前的一个校验条件。
在类ProxyTransactionManagementConfiguration中。
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
//注入解析器
//判断是否canApply的时候会用上
//会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解
advisor.setTransactionAttributeSource(transactionAttributeSource());
//设置增强advice 其实就是TransactionInterceptor
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
@Nullable
private TransactionAttributeSource transactionAttributeSource;
private final TransactionAttributeSourcePointcut pointcut
= new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
public void setTransactionAttributeSource
(TransactionAttributeSource transactionAttributeSource) {
//使用事务注解导入的 AnnotationTransactionAttributeSource
this.transactionAttributeSource = transactionAttributeSource;
}
}
@SuppressWarnings("serial")
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource
implements Serializable {
//省略部分代码
// 无参构造方法
public AnnotationTransactionAttributeSource() {
this(true);
}
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
//省略部分代码
}
// 省略部分代码
// 第一个布尔条件的方法
@Override
protected boolean allowPublicMethodsOnly() {
return this.publicMethodsOnly;
}
// 省略部分代码
}
其实allowPublicMethodsOnly()方法只是简单的将变量publicMethodsOnly的值返回了而已。
并且我们可以看到,其实这个publicMethodsOnly的值,在无参构造方法中被默认设置为了true,那么这个publicMethodsOnly是什么含义呢?其实从名字上来看,它是“仅限public方法”的意思,其实就是一个标识罢了,默认为true。
method.getModifiers()其实就是获取方法的修饰符,比如这个方法是public修饰的还是private修饰的,就是这个意思。Modifier.isPublic()方法的意思就非常明显了,说白了就是用来判断当前方法是不是public方法,如果是public方法就返回true,否则返回false。
分析到这里,答案就呼之欲出了,上边的代码说白了就是,在默认情况下,只允许public方法进行事务处理,所以当目标方法不是public方法时,那么红框中的表达式就为true,此时就会返回null。
我们知道,这里一旦返回null,那么当前正在匹配的BeanFactoryTransactionAttributeSourceAdvisor增强就不会加入到eligibleAdvisors中,从而导致TransactionInterceptor增强不会生效,那么此时就表示,该目标类不需要被代理,也就是不会添加事务管理的功能。
这个其实就是在非public方法上,添加@Transactional事务失效的底层原因!
获取目标类或者目标方法上的@Transactional事务属性
主要调用了一个findTransactionAttribute()方法,并且将目标方法作为入参传递了进去,接着findTransactionAttribute()方法就会给我们返回事务属性TransactionAttribute。
@Nullable
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
if (attr != null) {
return attr;
}
}
return null;
}
其实从findTransactionAttribute()方法的名字上也可以看出,这个方法就是用来寻找事务属性的,ok,那现在我们就跟进去看看这个findTransactionAttribute()方法吧。
在findTransactionAttribute()方法中,又调用了determineTransactionAttribute()方法,所以核心逻辑还是在determineTransactionAttribute()方法中的。
而在determineTransactionAttribute()方法的逻辑其实很简单,就是遍历annotationParsers集合中的事务注解解析器,然后通过事务注解解析器的parseTransactionAnnotation()方法完成事务属性的解析。
通过debug我们可以看到,其实在annotationParsers集合中呢,就只有SpringTransactionAnnotationParser这一个注解解析器,那这就简单了,说白了就是,这里其实就是通过SpringTransactionAnnotationParser注解解析器来完成事务属性解析的。
ok,那现在还犹豫啥呢,我们直接进去SpringTransactionAnnotationParser瞅一眼呗,此时会看到下边的代码。
//目标类上找
@Override
@Nullable
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
return determineTransactionAttribute(clazz);
}
//目标方法上找
@Override
@Nullable
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
AnnotationAttributes attributes = AnnotatedElementUtils
.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}
我们可以看到,这里其实主要调用了工具类AnnotatedElementUtils中的findMergedAnnotationAttributes()方法来寻找事务属性的。
并且我们可以看到,在findMergedAnnotationAttributes()方法的入参中,有目标方法element和注解Transactional.class,说白了这里就是,要在目标方法上寻找@Transactional注解中配置的属性!
而这个findMergedAnnotationAttributes()方法呢,是工具类AnnotatedElementUtils中的静态方法,专门是用于在指定element上寻找特定注解的,比如在目标方法上寻找@Transactional事务注解。
其实这个AnnotatedElementUtils工具类呢,是在spring-core包下的,所以不是我们这里分析的重点,因此这个方法,我们就不往下深入分析了,有兴趣的同学可以往下继续跟踪下,我们就不花费时间在这里了。
那我们继续往下看,在获取到事务属性之后,就会调用parseTransactionAnnotation()方法做进一步处理,代码如下
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
Propagation propagation = attributes.getEnum("propagation");
rbta.setPropagationBehavior(propagation.value());
Isolation isolation = attributes.getEnum("isolation");
rbta.setIsolationLevel(isolation.value());
rbta.setTimeout(attributes.getNumber("timeout").intValue());
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value"));
List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
rbta.setRollbackRules(rollbackRules);
return rbta;
}
大家可以看到,其实这个parseTransactionAnnotation()方法要做的事情呢,就是将刚刚获取到的事务属性进一步封装到RuleBasedTransactionAttribute中去,这样方便后续的处理,最后就会将封装好的RuleBasedTransactionAttribute作为结果返回。
而当computeTransactionAttribute()方法将事务属性返回之后,发现事务属性不为null,那这个时候就会将事务属性放入缓存attributeCache中,接着getTransactionAttribute()方法就会将事务属性返回。
else{
// 如果找到方法上的@Transactional注解 那么放到缓存里 下次不用再找了
String methodIdentification
= ClassUtils
.getQualifiedMethodName(method, targetClass);
if (txAttr instanceof DefaultTransactionAttribute) {
((DefaultTransactionAttribute) txAttr)
.setDescriptor(methodIdentification);
}
//放入缓存
this.attributeCache.put(cacheKey, txAttr);
}
//所以这里返回的是@Transactional注解上的属性
return txAttr;
可以看到,这里就会根据getTransactionAttribute()方法返回的事务属性进行判断,如果获取的事务属性不为null的话,那么就说明匹配成功,也就是说,此时目标类是需要被代理的!
上边呢,是获取事务属性不为null的情况,下边我们来看下另外一种情况,那就是获取到的事务属性为null的情况。
如果获取到的事务属性为null的话,则会返回false,那么此时BeanFactoryTransactionAttributeSourceAdvisor就不会加入到eligibleAdvisors中,从而导致TransactionInterceptor增强不会生效,那么此时就表示该目标方法不会被代理,也就是不会添加事务管理的功能。
所以对于@Transactional注解来说,在方法级别的匹配,说白了就是,看下能不能获取到@Transactional注解中配置的属性。
如果可以获取到事务属性的话,那么就表示BeanFactoryTransactionAttributeSourceAdvisor增强匹配成功,此时就会按照配置的事务属性来管理事务了。
而如果获取不到事务属性的话,那么BeanFactoryTransactionAttributeSourceAdvisor增强就不会生效,此时就说明当前目标方法所在的类不需要被代理,所以也就没有事务管理的功能了。
获取目标类上的@Transactional的事务属性
刚才呢,我们分析的是,在方法上顺利找到@Transactional注解的情况,那么另外一种情况,那就是可能在目标方法上是找不到@Transactional注解的,那么这种情况下,Spring又是怎么处理的呢?
我们此时假设,在目标方法上没有找到@Transactional注解。
也就是说,当在方法上找不到@Transactional注解时,那么txAttr就为null,那此时txAttr != null的结果就为false,那此时代码就会继续往下执行,也就是会执行下面的代码。
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
并且我们可以看到,这里调用的还是findTransactionAttribute()方法,和刚才在目标方法寻找事务属性是同一个方法。
通过上图,我们可以看到,方法名是一样的,而入参不一样,之前在目标方法上寻找事务属性时,入参传递的是目标方法本身,而这里在目标类上寻找事务属性时,入参传的是目标类本身,所以我们猜测这个findTransactionAttribute()方法可能是有两个重载方法,说白了就是方法名相同,但方法参数类型不同。
那到底是不是如我们猜测的那样呢?
我们进去看下就知道了,此时我们跟着进去findTransactionAttribute(specificMethod.getDeclaringClass())方法,会看到下边.
//目标类上找
@Override
@Nullable
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
return determineTransactionAttribute(clazz);
}
//目标方法上找
@Override
@Nullable
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
AnnotationAttributes attributes = AnnotatedElementUtils
.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}
上边的代码中,一个是在目标类级别上找事务属性的方法,一个是在目标方法级别找事务属性的方法,可以看到,它们都同时调用了determineTransactionAttribute()方法。
这就奇怪了,为啥这里在目标类上,寻找事务注解还是调用这个方法呢?难道是这个determineTransactionAttribute()方法同时支持在类上和方法上查找注解?
我们注意到,其实这个方法的入参是AnnotatedElement类型,从名字上来看,这个AnnotatedElement是“注释元素”的意思,那么这个AnnotatedElement到底代表哪些元素呢?
这个简单,其实我们点进去,来看下AnnotatedElement的定义就知道了。
我们可以看到,其实我们平常经常使用的Class和Method,甚至Field和Constructor,它们都是AnnotatedElement接口的实现类,也就是说,它们都属于“注释元素”。AnnotatedElement接口的一个实例,就表示当前JVM中的一个“被注解元素”,而这个被注解的元素可以是Class、Method、Field、Constructor等等。所以话说回来,由于这个determineTransactionAttribute()方法处理的AnnotatedElement接口类型,也就是说人家处理的是“被注解的元素。
既然处理的是被注解的元素,那当然就包含了Class、Method、Field、Constructor等元素,所以人家当然既可以来处理类上的事务属性和方法上的事务属性啦。
所以一句话,在类上寻找事务注解的逻辑,和在方法上寻找事务注解的逻辑是一模一样的,它们都是通过调用determineTransactionAttribute()方法来完成的!而最后,其实就是通过SpringTransactionAnnotationParser事务注解解析器来完成解析的。
假如我们此时在类上找到了事务属性,那么这个时候就会将事务属性给返回。
那大家思考下,现在这个情况,大概是一个怎样的业务场景呢?
其实啊,这个业务场景就是,@Transactional注解没有加在方法上,而是加在了类上!
虽然我们在工作中,一般不会加在类上,但是@Transactional注解本身,人家是既支持加在方法上,也支持加在类上的,所以在解析@Transactional注解的时候,Spring会优先从方法上获取事务属性,如果方法上找不到事务属性的话,那么接着就会看下方法所在的类上,是否加了@Transactional注解,就是这个意思。
在类级别和方法级别都满足后,就会将匹配成功的增强返回,而这里返回的增强其实就是BeanFactoryTransactionAttributeSourceAdvisor,我们知道,在BeanFactoryTransactionAttributeSourceAdvisor中有一个非常关键的属性,那就是adviceBeanName,它的值就是TransactionInterceptor类的全限定类名,而这个TransactionInterceptor的重要性,我们这里就不再赘述了。
一旦这个BeanFactoryTransactionAttributeSourceAdvisor增强被加入eligibleAdvisors中,就意味着事务功能添加成功了!那有的同学会问:“什么?我到现在还是没看到TransactionInterceptor增强啊”
其实呢,大家注意看上图中的红框,我们会发现在BeanFactoryTransactionAttributeSourceAdvisor中,有一个属性叫做adviceBeanName,而这个adviceBeanName的值就是TransactionInterceptor的全限定类名。
所以,我们心心念的TransactionInterceptor,其实就是BeanFactoryTransactionAttributeSourceAdvisor中的一个属性罢了,只不过这里是一个全限定类名,但是到后边一定会通过这个全限定类名来构建TransactionInterceptor实例的。
因为源码版本不同 所以略有差异,我这个版本是直接设置transactionInterceptor进去。
//看这里
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
//注入解析器
//判断是否canApply的时候会用上
//会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解
advisor.setTransactionAttributeSource(transactionAttributeSource());
//设置增强advice
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
4.生成代理对象
5.执行方法创建拦截器链
事务AOP代理是怎么来匹配BeanFactoryTransactionAttributeSourceAdvisor增强的?
那我们这里,就以jdk代理为例,当调用代理对象中的方法时,就会调用到JdkDynamicAopProxy的invoke()方法,而invoke()方法的核心代码如下。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 省略部分代码
try {
// 省略部分代码
// 获取当前要调用方法的拦截器链,advised就是一个ProxyFactory
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 处理拦截器链
if (chain.isEmpty()) {
// 如果拦截器链为空,则使用反射调用目标方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection
(target, method, argsToUse);
}
else {
//如果拦截器链不为空,则将拦截器统一封装为MethodInvocation
//同时传入目标对象target和目标方法method,后续反射调用目标方法会使用到
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 处理拦截器链,也就是依次执行每一个拦截器
retVal = invocation.proceed();
}
// 省略部分代码
// 将返回值作为结果返回
return retVal;
}
finally {
// 省略部分代码
}
}
其实JdkDynamicAopProxy的invoke()方法,我们在AOP章节详细分析过,这里呢,主要是站在事务代理的角度,来分析下事务代理的执行过程。
通过上边代码,可以看到,其实invoke()方法核心逻辑就两块,一个是获取拦截器链,一个是执行拦截器链,而执行拦截器链,在一开始讲@Transactional注解的时候就分析过了,下边我们主要来看下获取拦截器链的逻辑。
那我们现在就来看下getInterceptorsAndDynamicInterceptionAdvice()方法
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
//获取proxyFactory的advisors
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass
= (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
//遍历advisors
for (Advisor advisor : advisors) {
//判断类级别匹配
if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
//不管是事务还是aop预过滤一般都是true
//InfrastructureAdvisorAutoProxyCreator
//AnnotationAwareAspectJAutoProxyCreator
//都继承自AbstractAdvisorAutoProxyCreator
//AbstractAdvisorAutoProxyCreator#advisorsPreFiltered
//第二个条件:
//对于aop来说:使用切面表达式和类匹配
//对于事务来说:使用ClassFilter.TRUE 永远返回true
if (config.isPreFiltered() || pointcutAdvisor.getPointcut()
.getClassFilter().matches(actualClass)) {
//方法匹配器
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
//方法签名匹配
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions
(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm)
.matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
//匹配通过
if (match) {
//获取拦截器
MethodInterceptor[] interceptors
= registry.getInterceptors(advisor);
if (mm.isRuntime()) {
for (MethodInterceptor interceptor : interceptors) {
interceptorList
.add(new InterceptorAndDynamicMethodMatcher
(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
//将transactionInterceptor放入拦截器链
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
getAdvice方法对于Aop来说是使用增强注解和方法匹配返回MethodInterceptor。
getAdvice方法对于事务来说是使用adviceBeanName 来获取TransactionInterceptor。
public Advice getAdvice() {
Advice advice = this.advice;
//这个advice在构建BeanFactoryTransactionAttributeSourceAdvisor时已经创建了
if (advice != null) {
return advice;
}
Assert.state(this.adviceBeanName != null, "'adviceBeanName' must be specified");
Assert.state(this.beanFactory != null, "BeanFactory must be set to comresolve 'adviceBeanName'");
if (this.beanFactory.isSingleton(this.adviceBeanName)) {
// Rely on singleton semantics provided by the factory.
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
this.advice = advice;
return advice;
}
else {
synchronized (this.adviceMonitor) {
advice = this.advice;
if (advice == null) {
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
this.advice = advice;
}
return advice;
}
}
}
//看这里
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
//注入解析器
//判断是否canApply的时候会用上
//会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解
advisor.setTransactionAttributeSource(transactionAttributeSource());
//设置增强advice
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
首先第一步,就是从代理配置ProxyFactory中,获取到当时设置的增强,也就是BeanFactoryTransactionAttributeSourceAdvisor。
然后第二步,就是在类级别进行匹配,这个前边我们刚讲过的哈,其实对于@Transactional注解类级别的匹配来说,只要目标类既不是java自己的类,也不是Spring里的Ordered接口类型,那么此时就表示目标类是满足类级别匹配的。(源码版本不同,我的源码是一直返回true)
如果在类级别匹配成功的话,那么就进行第三步的处理,其实第三步的话,就是在方法级别进行匹配,匹配逻辑呢,前边我们刚讲过,其实就是看下目标方法或目标方法所在的类上有没有加@Transactional注解,如果加的话,那么就说明在方法级别匹配成功。
最后第四步的话,就是为匹配成功的增强构建拦截器了。
对于事务AOP代理来说,其实拦截器链chain中只有一个TransactionInterceptor拦截器,而TransactionInterceptor拦截器执行的整个过程,我们在事务源码分析的开头,就已经分析过了,所以这里就不再赘述了,说白了TransactionInterceptor拦截器就是基于jdbc的API来控制数据库事务的
下面看这一段代码:
// 处理拦截器链
if (chain.isEmpty()) {
// 如果拦截器链为空,则使用反射调用目标方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection
(target, method, argsToUse);
}
else {
// 如果拦截器链不为空,则将拦截器统一封装为MethodInvocation
// 同时传入目标对象target和目标方法method,后续反射调用目标方法会使用到
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 处理拦截器链,也就是依次执行每一个拦截器
retVal = invocation.proceed();
}
6.TransactionInterceptor
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
//将ReflectiveMethodInvocation的proceed方法作为参数传递
return invokeWithinTransaction
(invocation.getMethod(), targetClass, invocation::proceed;
}
//invocation 拦截器核心逻辑
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//获取设置的事务管理器
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// 开启事务
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// 调用目标方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 回滚事务
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure
(retVal, txAttr, status);
}
}
// 提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
//省略部分代码
}
}
上边就是invokeWithinTransaction()方法的核心代码了,其中一些不太重要的代码已经省略了
我们可以看到,上边的代码中,首先是调用了一个createTransactionIfNecessary()方法,从这个方法的名字上来看是“创建事务”的意思,其实说白了就是开启事务的意思。
接着调用了retVal = invocation.proceedWithInvocation()这行代码来执行目标方法,而这行代码呢,做了try catch处理,在这个catch语句块中调用了一个completeTransactionAfterThrowing()方法,这个方法从名字来看是“发生异常后完成事务”,其实说白了就是发生异常时回滚事务的意思,并且回滚完事务之后,通过throw ex将异常直接抛了出去。
如果执行目标方法没有发生异常,那么就会调用commitTransactionAfterReturning()方法,从名字上来看这个方法是“返回后提交事务”的意思,其实说白了就是目标方法正常执行结束后,如果没有发生异常,那么就直接提交事务的意思。
大家有没有发现,上边这块代码的逻辑,和上节我们基于AOP模拟事务的代码非常相似?简直就是一个模子里刻出来的。
其实啊,@Transactional注解的本质就是基于AOP来实现的,而实现事务的核心逻辑,其实就是在执行目标方法之前,先开启事务,然后再来执行目标方法,因为目标方法是加了try catch处理的,所以当执行目标方法发生异常时,由catch语句块来做特殊处理,说白了就是回滚事务,如果未发生异常,那么就直接提交事务,就这么简单。
7.查找对应的事务管理器
@Nullable
protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
// Do not attempt to lookup tx manager if no tx attributes are set
if (txAttr == null || this.beanFactory == null) {
return getTransactionManager();
}
//获取@Transactional注解的value属性
//如果没有指定 默认是""
//myPlatformTransactionManager
String qualifier = txAttr.getQualifier();
//如果不为空字符串进入这里
//如果指定了值 那么使用指定的名称和类型PlatformTransactionManager去找
//找到了直接返回
if (StringUtils.hasText(qualifier)) {
return determineQualifiedTransactionManager
(this.beanFactory, qualifier);
}
else if (StringUtils.hasText(this.transactionManagerBeanName)) {
return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
}else {
//调用TransactionInterceptor的getTransactionManager方法
//获取PlatformTransactionManager
PlatformTransactionManager defaultTransactionManager
= getTransactionManager();
if (defaultTransactionManager == null) {
//缓存中获取
defaultTransactionManager
= this.transactionManagerCache.get
(DEFAULT_TRANSACTION_MANAGER_KEY);
if (defaultTransactionManager == null) {
//根据类型获取
//但是如果根据类型查找如果有多个会有问题!
defaultTransactionManager
= this.beanFactory.getBean
(PlatformTransactionManager.class);
//放入缓存
this.transactionManagerCache.putIfAbsent(
DEFAULT_TRANSACTION_MANAGER_KEY,
defaultTransactionManager);
}
}
return defaultTransactionManager;
}
}
总结
1.获取所有的advisor
2.获取可用的advisor
3.从advisor中获取advice然后适配为MethodInterceptor
4.调用代理类的方法时会根据调用的方法匹配所有的MethodInterceptor组成chain
5.递归调用chain