likes
comments
collection
share

33.Spring事务源码之整体流程

作者站长头像
站长
· 阅读数 11

整体流程

第一步是注入自定义的事务管理器。

第二步是注入事务相关组件。

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的定义就知道了。

33.Spring事务源码之整体流程

我们可以看到,其实我们平常经常使用的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增强啊”

33.Spring事务源码之整体流程

其实呢,大家注意看上图中的红框,我们会发现在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