IOC容器初始化之AOP内部机制

Spring内部的AOP机制[待完善,各个类在AOP中处理的作用,以便深入理解AOP的内部机制]


【这种排版方式,是为了解决多个命名相同又调用,即便是代码debug,跟着跟,也会跟丢,所以,通过这种排版,理顺一下调用链,加深理解】

一、建立Spring的AOP【@Aspect或者@Transactional】机制的内部环境

1、前言

Spring提供了两种开启AOP的方式,一种是通过Xml的方式:aop:aspectj-autoproxy/,另一种是通过**@EnableAspectJAutoProxy方式。
不管是何种启用方式,AnnotationAwareAspectJAutoProxyCreator对象的创建都需要先被IOC容器解析成为BeanDefinition,然后Spring再从该BeanDefinition中创建该对象。两种方式被解析成BeanDefinition的方式不同,一种是通过
AopNamespaceHandler**,另一种是通过基于Spring环境下的注解驱动AspectJAutoProxyRegistrar,该类是Spring Aop中的核心对象要在IOC容器中解析成BeanDefinition并注册的。【再次回顾一下基于Spring环境下的注解开发的实现,另一种注解驱动的可参考Dubbo的**@EnableDubbo**,以此巩固Spring环境下的注解驱动开发过程。】
在创建AnnotationAwareAspectJAutoProxyCreator的对象时,通过BeanFactoryAware来为AOP提供BeanFactory的环境。【从Spring提供的各种Aware接口可以看出,这是为了方便扩展Spring而提供的接口】。该接口被执行的时机是在对象创建的initializeBean阶段中。依赖如下:

AnnotationAwareAspectJAutoProxyCreator

2、AnnotationAwareAspectJAutoProxyCreator的环境创建流程

2.1、 @Aspect入口

Spring AOP的内部环境的建立是在AnnotationAwareAspectJAutoProxyCreator对象创建的initializeBean阶段中【这里的AOP指的是用**@Aspect注解的,不是@Async**的AOP环境建立】。

	AbstractAutowireCapableBeanFactory::invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
			}
			if (bean instanceof BeanFactoryAware) {
			    // 1.spring aop环境的建立入口【注释中的阿拉伯数字代表了创建SpringAOP环境时的执行顺序】
			    // 这个bean对象指的是
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

AnnotationAwareAspectJAutoProxyCreator的bean后置处理器创建完成之后,第一次被执行的时机在registerBeanPostProcessors中的第三个阶段nonOrderedPostProcessorNames。此时,来看看之前各个类在AOP机制中的作用。
AbstractAutoProxyCreator:postProcessBeforeInstantiation() 对创建的bean是否要进行拦截并AOP处理。这个类是链接点,创建AOP代理对象。在这里createProxy。接着触发ProxyFactory的创建。从这里引申出面试点。

  • Q:Spring AOP的入口是哪里?
  • A:AnnotationAwareAspectJAutoProxyCreator,这其实是一个BeanPostProcessor。在populateBean中或者initializeBean中都会起作用。实际是createProxy方法。(这有个问题,这里所说的在populateBean中起作用,并不是真正创建代理。只是populateBean中,该processor的相关方法被不作处理的执行了一次。实际创建代理对象是在initializeBean的postProcessAfterInitialization的方法。)
  • Q:Spring创建代理的方式有几种?默认是哪种?
  • A:cglib代理和jdk动态代理。默认是基于一个或更多接口的JDK动态代理。若指定proxyTargetClass,则使用CGLIB代理。
    ProxyFactory是Spring AOP 提供了基于编码的方式创建AOP proxies Factory,而不是在beanFactory通过声明式的设置。
    ProxyCreatorSupport是proxy factories的基类,提供对一个可配置的AopProxyFactory的方便的访问(持有该引用对象)【在创建ProxyCreatorSupport的时候,接着创建了DefaultAopProxyFactory。】。
    DefaultAopProxyFactory创建CGLIB或者JDK动态代理的AopProxyFactory的默认实现。

2.2、AnnotationAwareAspectJAutoProxyCreator具体的环境创建

2.2.1、AbstractAdvisorAutoProxyCreator设置beanFactory
    // Helper for retrieving standard Spring Advisors from a BeanFactory, for use with auto-proxying.
	// 对于使用自动代理,可以从BeanFactory中获取标准的Spring Advisors 帮助类,赋值的时机在子类初始化beanFactory的时候
	private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;
	
	// 2.在创建完AnnotationAwareAspectJAutoProxyCreator该对象并初始化的过程中invokeAwareMethods这一阶段中
	// 完成对Spring AOP环境所需要的对beanFactory的持有。以便Spring AOP能够访问beanFactory中的方法跟数据
	@Override
	public void setBeanFactory(BeanFactory beanFactory) {
	    // 将Spring的IOC容器保存到AbstractAutoProxyCreator中
		super.setBeanFactory(beanFactory);
		if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
			throw new IllegalStateException("Cannot use AdvisorAutoProxyCreator without a ConfigurableListableBeanFactory");
		}
		// 初始化Spring AOP的环境,先执行的是AnnotationAwareAspectJAutoProxyCreator中的initBeanFactory方法
		initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
	}
2.2.2、AbstractAutoProxyCreator中beanFactory的赋值

这个类实现了BeanFactoryAware,beanFactory会因此被赋值,在创建相关对象的时候,就是为了提供对外访问Spring内部相关对象的入口,这也是Spring中Aware接口的作用。

	@Override
	public void setBeanFactory(BeanFactory beanFactory) {
		this.beanFactory = beanFactory;
	}
2.2.3、AnnotationAwareAspectJAutoProxyCreator的initBeanFactory

初始化Spring AOP中的工厂,对IOC容器中的beanFactory进行包装加工,使之能用于Spring AOP的,所以才说是initBeanFactory。注意,别理解成改变了它的行为。【这是我阅读代码时遇到的命名困惑,再次回看时,想通的,稍微注解一下。】

	// 3.创建Spring AOP【@Aspect和@Transational】的环境【findAdvisor和buildAdvisor】
	@Override
	protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	    // 触发父类AbstractAdvisorAutoProxyCreator,创建可以从BeanFactory中获取Spring Advisors的帮助类。
		super.initBeanFactory(beanFactory);
		// 【这个对象的含义需要再次认清】
		if (this.aspectJAdvisorFactory == null) {
			this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
		}
		// 创建AspectJ Advisors的帮助类
		// Helper for retrieving @AspectJ beans from a BeanFactory and building Spring Advisors based on them, 
		// for use with auto-proxying.
		// 5. buildAdvisor from method 中
		this.aspectJAdvisorsBuilder =
				new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
	}
2.2.4 AbstractAdvisorAutoProxyCreator的initBeanFactory
	// 4.子类AnnotationAwareAspectJAutoProxyCreator调用父类,触发的
	protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 这个变量起作用的时机,是在bean对象创建的过程中,由AOP的BeanPostProcessor触发,postProcessAfterInitialization方法
        // 这个变量的作用的时机,就是bean对象创建的initializeBean的初始化完成后,被执行的applyBeanPostProcessorsAfterInitialization。
        // 【回看,想通的,与BeanFactoryAspectJAdvisorsBuilderAdapter区别,我的理解是,这个是从beanDefiniton中获取的Advisor,即容器中声明过的Advisor;而BeanFactoryAspectJAdvisorsBuilderAdapter这个,我的理解是,从method中构建出Advisor】
		this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
	}

3、AnnotationAwareAspectJAutoProxyCreator的创建代理对象流程

3.1、创建代理的入口【父类AbstractAutoProxyCreator】

持有基本【DefaultListableBeanFactory】的BeanFactory容器
这段代码起作用的时机,是在bean对象被IOC容器创建后,初始化完成该bean对象后,由AOP的BeanPostProcessor触发,判断该对象是否要进行Spring AOP代理

	/**
	 * Create a proxy with the configured interceptors if the bean is
	 * identified as one to proxy by the subclass.
	 * @see #getAdvicesAndAdvisorsForBean
	 */
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
			    // a. spring AOP代理【英文字母Spring AOP代理对象的执行顺序,比如@Aspect】
			    // 对IOC容器已经创建完的对象进行包装,如果需要代理的话
			    // 这个包装指的是,是返回原生对象还是代理对象
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

3.2、判断是否要对容器创建完的对象应用代理【AbstractAutoProxyCreator】

	/**
	 * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
	 * @param bean the raw bean instance
	 * @param beanName the name of the bean
	 * @param cacheKey the cache key for metadata access
	 * @return a proxy wrapping the bean, or the raw bean instance as-is
	 */
	AbstractAutoProxyCreator::wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		// 已经判断过且明确不需要代理的
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		// shouldSkip中有找是否有Advisor【是否要跳过代理】
		// isInfrastructureClass先执行的AnnotationAwareAspectJAutoProxyCreator
		// 首先,如果目标类是基类的,就不需要Spring AOP代理
		// 其次,如果不是基类的话,再次判断是否需要跳过AOP代理
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		    // 如果开启了Spring AOP功能,那么所有IOC容器中的业务bean对象被初始化完成后,都会存放到advisedBean
		    // 集合中
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}
		// Create proxy if we have advice.
		// d 找到是否可以进行SpringAOP代理的
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}
		
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}
3.2.1、AnnotationAwareAspectJAutoProxyCreator的isInfrastructureClass

判断这个目标类是否是基础设施类

	@Override
	protected boolean isInfrastructureClass(Class<?> beanClass) {
		// Previously we setProxyTargetClass(true) in the constructor, but that has too
		// broad an impact. Instead we now override isInfrastructureClass to avoid proxying
		// aspects. I'm not entirely happy with that as there is no good reason not
		// to advise aspects, except that it causes advice invocation to go through a
		// proxy, and if the aspect implements e.g the Ordered interface it will be
		// proxied by that interface and fail at runtime as the advice method is not
		// defined on the interface. We could potentially relax the restriction about
		// not advising aspects in the future.
		return (super.isInfrastructureClass(beanClass) ||
				(this.aspectJAdvisorFactory != null && 
				this.aspectJAdvisorFactory.isAspect(beanClass)));
	}
3.2.2、AbstractAspectJAdvisorFactory的isAspect

判断目标类是否被@Aspect注解声明,且还不能被AJC编译(原因简单就是在AspectJ的1.5以下的版本中,也有这个注解,但是却不能被Spring AOP使用)

	/**
	 * We consider something to be an AspectJ aspect suitable for use by the Spring AOP system
	 * if it has the @Aspect annotation, and was not compiled by ajc. The reason for this latter test
	 * is that aspects written in the code-style (AspectJ language) also have the annotation present
	 * when compiled by ajc with the -1.5 flag, yet they cannot be consumed by Spring AOP.
	 */
	@Override
	public boolean isAspect(Class<?> clazz) {
		return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
	}

	private boolean hasAspectAnnotation(Class<?> clazz) {
		return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
	}

	/**
	 * We need to detect this as "code-style" AspectJ aspects should not be
	 * interpreted by Spring AOP.
	 */
	private boolean compiledByAjc(Class<?> clazz) {
		// The AJTypeSystem goes to great lengths to provide a uniform appearance between code-style and
		// annotation-style aspects. Therefore there is no 'clean' way to tell them apart. Here we rely on
		// an implementation detail of the AspectJ compiler.
		for (Field field : clazz.getDeclaredFields()) {
			if (field.getName().startsWith(AJC_MAGIC)) {
				return true;
			}
		}
		return false;
	}
3.2.3、AbstractAutoProxyCreator中的shouldSkip

AbstractAutoProxyCreator提供了默认不跳过代理的实现,其AspectJAwareAdvisorAutoProxyCreator
这段代码被触发的时机是由AbstractAutoProxyCreator中的shouldSkip触发

    // b.判断是否要跳过AnnotationAwareAspectJAutoProxyCreator这个SpringAOP后置处理器对bean对象创建初始化完成后的代理处理
	@Override
	protected boolean shouldSkip(Class<?> beanClass, String beanName) {
		// TODO: Consider optimization by caching the list of the aspect names
		// 这个findCandidateAdvisors是调用父类AbstractAdvisorAutoProxyCreator的
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		for (Advisor advisor : candidateAdvisors) {
			if (advisor instanceof AspectJPointcutAdvisor) {
				if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
					return true;
				}
			}
		}
		// 父类的一直返回false
		return super.shouldSkip(beanClass, beanName);
	}

3.3、判断是否需要AOP代理【AbstractAutoProxyCreator】

AbstractAutoProxyCreator中的方法是一个模板方法,具体实现在子类AbstractAdvisorAutoProxyCreator中

    // e. 由AbstractAutoProxyCreator这个类调用,触发时机在其wrapIfNecessary方法执行完shouldSkip之后
	@Override
	@Nullable
	protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
		// f. 依据这个判断,是否需要返回创建对象的代理对象
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			// 这个 DO_NOT_PROXY = null,用语义替代null,便于理解
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}
	/**
	 * Find all eligible Advisors for auto-proxying this class.
	 * @param beanClass the clazz to find advisors for
	 * @param beanName the name of the currently proxied bean
	 * @return the empty List, not {@code null},
	 * if there are no pointcuts or interceptors
	 * @see #findCandidateAdvisors
	 * @see #sortAdvisors
	 * @see #extendAdvisors
	 */
	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		// f.1 第一步:获取所有的Advisor
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		// f.2 第二步:从所有的Advisor中选出能够用于目标类的Advisor
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}
3.3.1、从容器中找到所有的Advisor

从容器中找到用自动代理的所有的Advisor

	/** AbstractAdvisorAutoProxyCreator
	 * Find all candidate Advisors to use in auto-proxying.,子类调用
	 * @return the List of candidate Advisors
	 */
	protected List<Advisor> findCandidateAdvisors() {
		// c.找IOC容器中所有的Advisor
		// BeanFactoryAdvisorRetrievalHelper这个类就是为了在Spring容器中找到所有的Advisor。这也解释了为什么该Helper类需要
		// beanFactory。
	    // 因为需要beanFactory中根据type=Advisor来获取该类型的beanName。
	    // 也就是该BeanPostProcessor为什么要实现BeanFactoryAware方法,提供对BeanFactory中数据的访问。
	    // ==总结:BeanFactoryAware是Spring容器向外部提供对beanFactory内部方法访问的机制。==
		return this.advisorRetrievalHelper.findAdvisorBeans();
	}
		// 由~Helper这个类具体做从SpringIOC容器中找到所有声明的Advisor
	BeanFactoryAdvisorRetrievalHelper::findAdvisorBeans() {
		// Determine list of advisor bean names, if not cached already.
		String[] advisorNames = null;
		synchronized (this) {
			// this.cachedAdvisorBeanNames 只调用一次
			// BeanFactoryUtils.beanNamesForTypeIncludingAncestors
			// 因为这个方法是从IOC容器中所有的beanDefinitionName中查找,因此,缓存的作用
			// 尽可能避免了web应用过大所造成的效率低下。
			advisorNames = this.cachedAdvisorBeanNames;
			if (advisorNames == null) {
				// Do not initialize FactoryBeans here: We need to leave all regular beans
				// uninitialized to let the auto-proxy creator apply to them!
				advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
						this.beanFactory, Advisor.class, true, false);
				this.cachedAdvisorBeanNames = advisorNames;
			}
		}
		if (advisorNames.length == 0) {
			return new LinkedList<>();
		}

		List<Advisor> advisors = new LinkedList<>();
		for (String name : advisorNames) {
			// 默认的,所有的Advisor都使用Spring AOP代理。该方法实现返回true
			if (isEligibleBean(name)) {
				// 对正在创建的bean不做代理
				if (this.beanFactory.isCurrentlyInCreation(name)) {
					if (logger.isDebugEnabled()) {
						logger.debug("Skipping currently created advisor '" + name + "'");
					}
				}
				else {
					try {
						// 使用bean对象的创建流程
						advisors.add(this.beanFactory.getBean(name, Advisor.class));
					}
					catch (BeanCreationException ex) {
						Throwable rootCause = ex.getMostSpecificCause();
						if (rootCause instanceof BeanCurrentlyInCreationException) {
							BeanCreationException bce = (BeanCreationException) rootCause;
							String bceBeanName = bce.getBeanName();
							if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
								if (logger.isDebugEnabled()) {
									logger.debug("Skipping advisor '" + name +
											"' with dependency on currently created bean: " + ex.getMessage());
								}
								// Ignore: indicates a reference back to the bean we're trying to advise.
								// We want to find advisors other than the currently created bean itself.
								continue;
							}
						}
						throw ex;
					}
				}
			}
		}
		return advisors;
	}
3.3.2、从所有的Advisor中过滤出能应用于目标对象的Advisor
	/**
	 * Search the given candidate Advisors to find all Advisors that
	 * can apply to the specified bean.
	 * @param candidateAdvisors the candidate Advisors
	 * @param beanClass the target's bean class
	 * @param beanName the target's bean name
	 * @return the List of applicable Advisors
	 * @see ProxyCreationContext#getCurrentProxiedBeanName()
	 */
	protected List<Advisor> findAdvisorsThatCanApply(
			List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
		ProxyCreationContext.setCurrentProxiedBeanName(beanName);
		try {
			// g.从候选者集筛选出可以应用到beanClass上的Advisors
			return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
		}
		finally {
			ProxyCreationContext.setCurrentProxiedBeanName(null);
		}
	}
	
	AopUtils::findAdvisorsThatCanApply(candidateAdvisors, beanClass) {
		if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		List<Advisor> eligibleAdvisors = new LinkedList<>();
		for (Advisor candidate : candidateAdvisors) {
			// 候选Advisor满足两个条件:
			// 1. 该Advisor实现了IntroductionAdvisor
			// 2. 该Advisor能匹配到目标类 
			if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
				eligibleAdvisors.add(candidate);
			}
		}
		boolean hasIntroductions = !eligibleAdvisors.isEmpty();
		for (Advisor candidate : candidateAdvisors) {
			if (candidate instanceof IntroductionAdvisor) {
				// already processed
				continue;
			}
			// h.具体做Advisors与创建并初始化完后bean的做匹配
			if (canApply(candidate, clazz, hasIntroductions)) {
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}
	/**
	 * Can the given pointcut apply at all on the given class?
	 * <p>This is an important test as it can be used to optimize
	 * out a pointcut for a class.
	 * @param pc the static or dynamic pointcut to check
	 * @param targetClass the class to test
	 * @param hasIntroductions whether or not the advisor chain
	 * for this bean includes any introductions
	 * @return whether the pointcut can apply on any method
	 */
	AopUtils::canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
		Assert.notNull(pc, "Pointcut must not be null");
		if (!pc.getClassFilter().matches(targetClass)) {
			return false;
		}
		// i.从切点中获取方法匹配器
		MethodMatcher methodMatcher = pc.getMethodMatcher();
		if (methodMatcher == MethodMatcher.TRUE) {
			// No need to iterate the methods if we're matching any method anyway...
			return true;
		}

		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}

		Set<Class<?>> classes = new LinkedHashSet<>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
		classes.add(targetClass);
		for (Class<?> clazz : classes) {
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method method : methods) {
				if ((introductionAwareMethodMatcher != null &&
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
						// j.@Transactional @Aspect @Async 都是用到这个逻辑匹配
						// 只不过是,两者具体的匹配方式不同。
						// 从这里不难发现,接口编程的重要性。
						// 同时,也能体会到抽象类的重要作用。抽象类一般是提供流程,涉及一些外调,通常是用接口来配合的
						// 这样,才能真正发挥抽象类和接口的作用【举例说明】
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}

		return false;
	}

AbstractAdvisorAutoProxyCreator

二、@Transactional的AOP内部机制

1、@Transactional的AOP环境的建立

@Transactional的AOP环境建立比较简单,只需要创建这三个对象:
BeanFactoryTransactionAttributeSourceAdvisor
TransactionAttributeSource:事务属性源,这个存在的作用就是能将AnnotationAttribute转换成TransactionAttribute
TransactionInterceptor:事务拦截器 => Advise
TransactionAttributeSourcePointcut:事务属性源切点 => Pointcut

2、@Transactional的类创建代理对象

  	
	// j.1 @Transactional的处理逻辑[要创建的代理对象,匹配逻辑]
	BeanFactoryTransactionAttributeSourceAdvisor->TransactionAttributeSourcePointcut::matches(Method method, 
		Class<?> targetClass) {
		if (TransactionalProxy.class.isAssignableFrom(targetClass)) {
			return false;
		}
		// j.1.1 获取的是BeanFactoryTransactionAttributeSourceAdvisor中的TransactionAttributeSource,作用域是在
		// BeanFactoryTransactionAttributeSourceAdvisor中的
		TransactionAttributeSource tas = getTransactionAttributeSource();
	    // j.1.2 获取的tas其实是AbstractFallbackTransactionAttributeSource对象
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}
	/**
	 * Determine the transaction attribute for this method invocation.
	 * <p>Defaults to the class's transaction attribute if no method attribute is found.
	 * @param method the method for the current invocation (never {@code null})
	 * @param targetClass the target class for this invocation (may be {@code null})
	 * @return TransactionAttribute for this method, or {@code null} if the method
	 * is not transactional
	 */
	@Override
	AbstractFallbackTransactionAttributeSource::getTransactionAttribute(Method method, Class<?> targetClass) {
		// First, see if we have a cached value.
		// j.1.2.1 判断这个方法的事物是否已存在缓存中
		Object cacheKey = getCacheKey(method, targetClass);
		Object cached = this.attributeCache.get(cacheKey);
		if (cached != null) {
			// Value will either be canonical value indicating there is no transaction attribute,
			// or an actual transaction attribute.
			if (cached == NULL_TRANSACTION_ATTRIBUTE) {
				return null;
			}
			else {
				return (TransactionAttribute) cached;
			}
		}
		else {
			// We need to work it out.
			// j.1.2.2 不在缓存中,就需要获取并重新放进缓存中
			TransactionAttribute txAtt = computeTransactionAttribute(method, targetClass);
			// j.1.2.3 Put it in the cache.
			if (txAtt == null) {
			    // 不进行事物
				this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
			}
			else {
				if (logger.isDebugEnabled()) {
					Class<?> classToLog = (targetClass != null ? targetClass : method.getDeclaringClass());
					logger.debug("Adding transactional method '" + classToLog.getSimpleName() + "." +
							method.getName() + "' with attribute: " + txAtt);
				}
				// 要事物管理的
				this.attributeCache.put(cacheKey, txAtt);
			}
			return txAtt;
		}
	}
	/**j.1.2.2 判断目标对象的方法是否要进行事物的管理
	 * Same signature as {@link #getTransactionAttribute}, but doesn't cache the result.
	 * {@link #getTransactionAttribute} is effectively a caching decorator for this method.
	 * <p>As of 4.1.8, this method can be overridden.
	 * @since 4.1.8
	 * @see #getTransactionAttribute
	 */
	protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
		// Don't allow no-public methods as required. 【事物必须要public方法】
		if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
			return null;
		}

		// Ignore CGLIB subclasses - introspect the actual user class.
		Class<?> userClass = ClassUtils.getUserClass(targetClass);
		// The method may be on an interface, but we need attributes from the target class.
		// If the target class is null, the method will be unchanged.
		Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
		// If we are dealing with method with generic parameters, find the original method.
		specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);

		// j.1.2.2.1 First try is the method in the target class.【先从方法中找事物,因此最好不要把@Transactional声明在类上】
		TransactionAttribute txAtt = findTransactionAttribute(specificMethod);
		if (txAtt != null) {
			return txAtt;
		}

		// j.1.2.2.2 Second try is the transaction attribute on the target class.
		txAtt = findTransactionAttribute(specificMethod.getDeclaringClass());
		if (txAtt != null) {
			return txAtt;
		}

		if (specificMethod != method) {
			// j.1.2.2.3 Fallback is to look at the original method.
			txAtt = findTransactionAttribute(method);
			if (txAtt != null) {
				return txAtt;
			}
			// j.1.2.2.4 Last fallback is the class of the original method.
			return findTransactionAttribute(method.getDeclaringClass());
		}
		return null;
	}
	
	/** [j.1.2.2.1 - j.1.2.2.4] 最终都会调用AnnotationTransactionAttributeSource的下述方法
	 * Determine the transaction attribute for the given method or class.
	 * <p>This implementation delegates to configured
	 * {@link TransactionAnnotationParser TransactionAnnotationParsers}
	 * for parsing known annotations into Spring's metadata attribute class.
	 * Returns {@code null} if it's not transactional.
	 * <p>Can be overridden to support custom annotations that carry transaction metadata.
	 * @param ae the annotated method or class
	 * @return TransactionAttribute the configured transaction attribute,
	 * or {@code null} if none was found
	 */
	protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) {
		if (ae.getAnnotations().length > 0) {
			for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
			    // 用的是SpringTransactionAnnotationParser
			    // 这个作用是将AnnotationAttribute转换成TransactionAttribute
				TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae);
				if (attr != null) {
					return attr;
				}
			}
		}
		return null;
	}

3、@Transactional执行事务的流程

这个是事务代理后的对象执行的invoke方法。【cglib代理的】

	/**
	 * General delegate for around-advice-based subclasses, delegating to several other template
	 * methods on this class. Able to handle {@link CallbackPreferringPlatformTransactionManager}
	 * as well as regular {@link PlatformTransactionManager} implementations and
	 * {@link ReactiveTransactionManager} implementations for reactive return types.
	 * @param method the Method being invoked
	 * @param targetClass the target class that we're invoking the method on
	 * @param invocation the callback to use for proceeding with the target invocation
	 * @return the return value of the method, if any
	 * @throws Throwable propagated from the target 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 TransactionManager tm = determineTransactionManager(txAttr);

		if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
			ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
				if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
					throw new TransactionUsageException(
							"Unsupported annotated transaction on suspending function detected: " + method +
							". Use TransactionalOperator.transactional extensions instead.");
				}
				ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
				if (adapter == null) {
					throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
							method.getReturnType());
				}
				return new ReactiveTransactionSupport(adapter);
			});
			return txSupport.invokeWithinTransaction(
					method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
		}

		PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

			Object retVal;
			try {
				// This is an around advice: Invoke the next interceptor in the chain.
				// This will normally result in a target object being invoked.
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				cleanupTransactionInfo(txInfo);
			}

			if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
				// Set rollback-only in case of Vavr failure matching our rollback rules...
				TransactionStatus status = txInfo.getTransactionStatus();
				if (status != null && txAttr != null) {
					retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
				}
			}

			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		else {
			final ThrowableHolder throwableHolder = new ThrowableHolder();

			// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
			try {
				Object result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
					TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
					try {
						Object retVal = invocation.proceedWithInvocation();
						if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
							// Set rollback-only in case of Vavr failure matching our rollback rules...
							retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
						}
						return retVal;
					}
					catch (Throwable ex) {
						if (txAttr.rollbackOn(ex)) {
							// A RuntimeException: will lead to a rollback.
							if (ex instanceof RuntimeException) {
								throw (RuntimeException) ex;
							}
							else {
								throw new ThrowableHolderException(ex);
							}
						}
						else {
							// A normal return value: will lead to a commit.
							throwableHolder.throwable = ex;
							return null;
						}
					}
					finally {
						cleanupTransactionInfo(txInfo);
					}
				});

				// Check result state: It might indicate a Throwable to rethrow.
				if (throwableHolder.throwable != null) {
					throw throwableHolder.throwable;
				}
				return result;
			}
			catch (ThrowableHolderException ex) {
				throw ex.getCause();
			}
			catch (TransactionSystemException ex2) {
				if (throwableHolder.throwable != null) {
					logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
					ex2.initApplicationException(throwableHolder.throwable);
				}
				throw ex2;
			}
			catch (Throwable ex2) {
				if (throwableHolder.throwable != null) {
					logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
				}
				throw ex2;
			}
		}
	}

三、@Async的AOP内部机制

1、@Async的AOP环境的建立

AsyncAnnotationBeanPostProcessor中的setBeanFactory创建AsyncAnnotationAdvisor

	@Override
	public void setBeanFactory(BeanFactory beanFactory) {
		super.setBeanFactory(beanFactory);

		Executor executorToUse = this.executor;
		if (executorToUse == null) {
			try {
				// Search for TaskExecutor bean... not plain Executor since that would
				// match with ScheduledExecutorService as well, which is unusable for
				// our purposes here. TaskExecutor is more clearly designed for it.
				// 从这可以看出,容器中只能有一个ThreadPoolTaskExecutor,当配置多个时候的会报错
				executorToUse = beanFactory.getBean(TaskExecutor.class);
			}
			catch (NoUniqueBeanDefinitionException ex) {
				try {
					executorToUse = beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
				}
				catch (NoSuchBeanDefinitionException ex2) {
					logger.info("More than one TaskExecutor bean found within the context, and none is " +
							"named 'taskExecutor'. Mark one of them as primary or name it 'taskExecutor' " +
							"(possibly as an alias) in order to use it for async annotation processing.");
				}
			}
			catch (NoSuchBeanDefinitionException ex) {
				logger.info("No TaskExecutor bean found for async annotation processing.");
				// Giving up -> falling back to default executor within the advisor...
			}
		}
		//  executorToUse = ThreadPoolTaskExecutor
		// 这里创建@Async的AOP环境。这个AOP环境其实就是【Advisor=Advice + Pointcut】
		// AsyncAnnotationAdvisor = AnnotationAsyncExecutionInterceptor + ComposablePointcut		
		AsyncAnnotationAdvisor advisor =  new AsyncAnnotationAdvisor(executorToUse, this.exceptionHandler);
		if (this.asyncAnnotationType != null) {
			advisor.setAsyncAnnotationType(this.asyncAnnotationType);
		}
		advisor.setBeanFactory(beanFactory);
		this.advisor = advisor;
	}

2、@Async注解的类创建代理对象的流程

Async注解的类的对象创建的入口【@Async所在的类要被创建代理对象的触发流程】

	// @Async的处理逻辑逻辑(指的是,被@Async声明的类或者它的方法的bean对象创建并初始化完成后,是否要生成代理对象)[@Async注解的类在
	// Spring中创建对象的initializeBean中的初始化完成后,由
	// AsyncAnnotationBeanPostProcessor这个后置处理器处理]
	@Override
	AsyncAnnotationBeanPostProcessor::AbstractAdvisingBeanPostProcessor::postProcessAfterInitialization(
					Object bean, String beanName) {
		if (this.advisor == null || bean instanceof AopInfrastructureBean) {
			// Ignore AOP infrastructure such as scoped proxies.
			return bean;
		}
		
		if (bean instanceof Advised) {
			Advised advised = (Advised) bean;
			if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
				// Add our local Advisor to the existing proxy's Advisor chain...
				if (this.beforeExistingAdvisors) {
					advised.addAdvisor(0, this.advisor);
				}
				else {
					advised.addAdvisor(this.advisor);
				}
				return bean;
			}
		}
		// A.1 判断是否要进行代理对象的创建
		if (isEligible(bean, beanName)) {
			ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
			if (!proxyFactory.isProxyTargetClass()) {
				evaluateProxyInterfaces(bean.getClass(), proxyFactory);
			}
			proxyFactory.addAdvisor(this.advisor);
			customizeProxyFactory(proxyFactory);
			// 默认情况下,创建的JDKDynamicProxy的代理对象
			return proxyFactory.getProxy(getProxyClassLoader());
		}

		// No proxy needed.
		return bean;
	}
	/**
	 * Check whether the given class is eligible for advising with this
	 * post-processor's {@link Advisor}.
	 * <p>Implements caching of {@code canApply} results per bean target class.
	 * @param targetClass the class to check against
	 * @see AopUtils#canApply(Advisor, Class)
	 */
	AbstractAdvisingBeanPostProcessor::isEligible(Class<?> targetClass) {
		Boolean eligible = this.eligibleBeans.get(targetClass);
		if (eligible != null) {
			return eligible;
		}
		if (this.advisor == null) {
			return false;
		}
		// B.1 @Async匹配,判断Async的advisor是否能用于目标类
		eligible = AopUtils.canApply(this.advisor, targetClass);
		// 类似缓存了
		this.eligibleBeans.put(targetClass, eligible);
		return eligible;
	}
	/**
	 * Can the given pointcut apply at all on the given class?
	 * <p>This is an important test as it can be used to optimize
	 * out a pointcut for a class.
	 * @param pc the static or dynamic pointcut to check
	 * @param targetClass the class to test
	 * @param hasIntroductions whether or not the advisor chain
	 * for this bean includes any introductions
	 * @return whether the pointcut can apply on any method
	 */
	public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
		Assert.notNull(pc, "Pointcut must not be null");
		if (!pc.getClassFilter().matches(targetClass)) {
			return false;
		}

		MethodMatcher methodMatcher = pc.getMethodMatcher();
		if (methodMatcher == MethodMatcher.TRUE) {
			// No need to iterate the methods if we're matching any method anyway...
			return true;
		}

		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}

		Set<Class<?>> classes = new LinkedHashSet<>();
		if (!Proxy.isProxyClass(targetClass)) {
			classes.add(ClassUtils.getUserClass(targetClass));
		}
		classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

		for (Class<?> clazz : classes) {
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method method : methods) {
				if (introductionAwareMethodMatcher != null ?
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
						//此时,@Async被执行的是MethodMatchers.matches方法
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}

		return false;
	}

3、@Async的执行代理对象的流程

当程序执行到@Async注解的方法时,会执行动态代理类中的重写的同名方法,如图所示:
在这里插入图片描述

3.1、JdkDynamicAopProxy的invoke方法

当程序执行到动态代理的同名方法,继续执行时,会走到这一步:

	/**
	 * Implementation of {@code InvocationHandler.invoke}.
	 * <p>Callers will see exactly the exception thrown by the target,
	 * unless a hook method throws an exception.
	 */
	@Override
	@Nullable
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object oldProxy = null;
		boolean setProxyContext = false;
		// this.advised = AsyncAnnotationAdvisor
		// 什么时候被赋的值?在创建完ProxyFactory之后,proxyFactory.addAdvisor(this.advisor);
		// 1. targetSource是代理对象
		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		try {
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				// The target does not implement the equals(Object) method itself.
				return equals(args[0]);
			}
			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				// The target does not implement the hashCode() method itself.
				return hashCode();
			}
			else if (method.getDeclaringClass() == DecoratingProxy.class) {
				// There is only getDecoratedClass() declared -> dispatch to proxy config.
				return AopProxyUtils.ultimateTargetClass(this.advised);
			}
			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				// Service invocations on ProxyConfig with the proxy config...
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal;

			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			// Get as late as possible to minimize the time we "own" the target,
			// in case it comes from a pool.
			// 2. targetSource.getTarget是真正的目标对象
			target = targetSource.getTarget();
			Class<?> targetClass = (target != null ? target.getClass() : null);

			// Get the interception chain for this method.
			// 3. 从目标类中的该方法找到Advice,对于@Async来说,就是AnnotationAsyncExecutionInterceptor
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			// Check whether we have any advice. If we don't, we can fallback on direct
			// reflective invocation of the target, and avoid creating a MethodInvocation.
			if (chain.isEmpty()) {
				// We can skip creating a MethodInvocation: just invoke the target directly
				// Note that the final invoker must be an InvokerInterceptor so we know it does
				// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
				// 4. We need to create a method invocation...
				MethodInvocation invocation =
						new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// Proceed to the joinpoint through the interceptor chain.
				retVal = invocation.proceed();
			}

			// Massage return value if necessary.
			Class<?> returnType = method.getReturnType();
			if (retVal != null && retVal == target &&
					returnType != Object.class && returnType.isInstance(proxy) &&
					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
				// Special case: it returned "this" and the return type of the method
				// is type-compatible. Note that we can't help if the target sets
				// a reference to itself in another returned object.
				retVal = proxy;
			}
			else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
				throw new AopInvocationException(
						"Null return value from advice does not match primitive return type for: " + method);
			}
			return retVal;
		}
		finally {
			if (target != null && !targetSource.isStatic()) {
				// Must have come from TargetSource.
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				// Restore old proxy.
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}

3.2、从目标类中的该方法找到Advice

由上述步骤3触发,在AdvisedSupport

	/**
	 * Determine a list of {@link org.aopalliance.intercept.MethodInterceptor} objects
	 * for the given method, based on this configuration.
	 * @param method the proxied method
	 * @param targetClass the target class
	 * @return a List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
	 */
	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
		MethodCacheKey cacheKey = new MethodCacheKey(method);
		List<Object> cached = this.methodCache.get(cacheKey);
		if (cached == null) {
			// 真正获取Advice的动作
			cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
					this, method, targetClass);
			// 放到缓存中		
			this.methodCache.put(cacheKey, cached);
		}
		return cached;
	}

3.2.1、真正获取Advise的动作

是由DefaultAdvisorChainFactory执行的

	@Override
	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, @Nullable Class<?> targetClass) {

		// This is somewhat tricky... We have to process introductions first,
		// but we need to preserve order in the ultimate list.
		AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
		Advisor[] advisors = config.getAdvisors();
		List<Object> interceptorList = new ArrayList<>(advisors.length);
		Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
		Boolean hasIntroductions = null;

		for (Advisor advisor : advisors) {
			if (advisor instanceof PointcutAdvisor) {
				// Add it conditionally.
				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
				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 {
						// 获取@Async对应的切点的方法匹配器MethodMatchers
						match = mm.matches(method, actualClass);
					}
					if (match) {
						// 匹配成功,获取该Advisor的方法拦截器
						MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
						if (mm.isRuntime()) {
							// Creating a new object instance in the getInterceptors() method
							// isn't a problem as we normally cache created chains.
							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;
	}

3.2.2、匹配成功后,获取方法拦截器

在经过上述的方法匹配成功后,从DefaultAdvisorAdapterRegistry中获取该Advisor(AsyncAnnotationAdvisor)的方法拦截器

	@Override
	public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List<MethodInterceptor> interceptors = new ArrayList<>(3);
		// 本例中,advisor = AsyncAnnotationAdvisor,其advice = AnnotationAsyncExecutionInterceptor
		Advice advice = advisor.getAdvice();
		if (advice instanceof MethodInterceptor) {
			interceptors.add((MethodInterceptor) advice);
		}
		// 这里再次应用了Adapter适配器模式
		// this.adapters总共有三种适配器
		// 1.MethodBeforeAdviceAdapter 2. AfterReturningAdviceAdapter 3. ThrowsAdviceAdapter
		// 此处的AnnotationAsyncExecutionInterceptor 都不是上述三个
		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]);
	}

3.3、执行方法拦截器

获取完方法拦截器后,继续下一步。执行3.1中的第四步,在ReflectiveMethodInvocation中执行。

	@Override
	@Nullable
	public Object proceed() throws Throwable {
		// We start with an index of -1 and increment early.
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
			if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				return proceed();
			}
		}
		else {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			// 执行该Advisor(AsyncAnnotationAdvisor)的方法拦截器(AnnotationAsyncExecutionInterceptor
			// )中的invoke方法
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

3.4、AnnotationAsyncExecutionInterceptor拦截器的invoke方法执行

以上过程,演示了@Async的方法拦截器如何被调用执行的,执行是在AsyncExecutionInterceptor中。

	/**
	 * Intercept the given method invocation, submit the actual calling of the method to
	 * the correct task executor and return immediately to the caller.
	 * @param invocation the method to intercept and make asynchronous
	 * @return {@link Future} if the original method returns {@code Future}; {@code null}
	 * otherwise.
	 */
	@Override
	@Nullable
	public Object invoke(final MethodInvocation invocation) throws Throwable {
		// 1. 获取目标类
		Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
		Method specificMethod = ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);
		final Method userDeclaredMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
		// 2. 获取异步任务执行器
		AsyncTaskExecutor executor = determineAsyncExecutor(userDeclaredMethod);
		if (executor == null) {
			throw new IllegalStateException(
					"No executor specified and no default executor set on AsyncExecutionInterceptor either");
		}
		// 3. 创建回调任务
		Callable<Object> task = () -> {
			try {
				Object result = invocation.proceed();
				if (result instanceof Future) {
					return ((Future<?>) result).get();
				}
			}
			catch (ExecutionException ex) {
				handleError(ex.getCause(), userDeclaredMethod, invocation.getArguments());
			}
			catch (Throwable ex) {
				handleError(ex, userDeclaredMethod, invocation.getArguments());
			}
			return null;
		};
		// 4. 向线程池中提交回调任务,在其父类AsyncExecutionAspectSupport中
		return doSubmit(task, executor, invocation.getMethod().getReturnType());
	}
	
	// 获取异步执行器
	/**
	 * Determine the specific executor to use when executing the given method.
	 * Should preferably return an {@link AsyncListenableTaskExecutor} implementation.
	 * @return the executor to use (or {@code null}, but just if no default executor is available)
	 */
	@Nullable
	protected AsyncTaskExecutor determineAsyncExecutor(Method method) {
		AsyncTaskExecutor executor = this.executors.get(method);
		if (executor == null) {
			Executor targetExecutor;
			// @Async注解的属性值value。即定义的ThreadPoolTaskExecutor的beanName
			String qualifier = getExecutorQualifier(method);
			if (StringUtils.hasLength(qualifier)) {
				targetExecutor = findQualifiedExecutor(this.beanFactory, qualifier);
			}
			else {
				// 这个赋值时机在创建AnnotationAsyncExecutionInterceptor时赋值
				targetExecutor = this.defaultExecutor.get();
			}
			if (targetExecutor == null) {
				return null;
			}
			executor = (targetExecutor instanceof AsyncListenableTaskExecutor ?
					(AsyncListenableTaskExecutor) targetExecutor : new TaskExecutorAdapter(targetExecutor));
			// 相当于放在缓存中,以后再次进入,直接获取。不需要再经过查找		
			this.executors.put(method, executor);
		}
		return executor;
	}

3.5、@Async的异步线程

子类AsyncExecutionIntercptor中提交自己创建的回调任务。

	/**
	 * Delegate for actually executing the given task with the chosen executor.
	 * @param task the task to execute
	 * @param executor the chosen executor
	 * @param returnType the declared return type (potentially a {@link Future} variant)
	 * @return the execution result (potentially a corresponding {@link Future} handle)
	 */
	@Nullable
	protected Object doSubmit(Callable<Object> task, AsyncTaskExecutor executor, Class<?> returnType) {
		if (CompletableFuture.class.isAssignableFrom(returnType)) {
			return CompletableFuture.supplyAsync(() -> {
				try {
					return task.call();
				}
				catch (Throwable ex) {
					throw new CompletionException(ex);
				}
			}, executor);
		}
		else if (ListenableFuture.class.isAssignableFrom(returnType)) {
			// 提交创建的回调任务
			// 这里需要注意,在对方法使用@Async注解的时候,如果该异步方法有返回值,返回类型只能是Future<?>这种
			// <?>这里的?可以指定具体的返回类型
			// 创建的异步结果用 return new AsyncResult<?>(result);
			// 注意:如果把该方法的返回结果声明为AsyncResult 会报ClassCastException。
			// org.springframework.util.concurrent.ListenableFutureTask cannot be cast to 
			// org.springframework.scheduling.annotation.AsyncResult
			// 因为创建的异步任务,执行的是这里
			return ((AsyncListenableTaskExecutor) executor).submitListenable(task);
		}
		else if (Future.class.isAssignableFrom(returnType)) {
			// 如果声明的返回类型为Future<?>这种,则就会执行这个提交任务
			return executor.submit(task);
		}
		else {
			executor.submit(task);
			return null;
		}
	}

3.6、AsyncAnnotationAdvisor的依赖

该类中两个重要的property:
Advice = AnnotationAsyncExecutionInterceptor
Pointcut = ComposablePointcut
AsyncAnnotationAdvisor

3.7 AsyncAnnotationAdvisor在Spring AOP中扮演的角色及作用

这个通知通过@Async注解激活异步方法的执行。在类或者接口或者方法都可以使用。也会检测EJB3.1的javax.ejb.Asynchronous的注解,就跟@Async效果一样。创建该Advisor代码:

	/**
	 * Create a new {@code AsyncAnnotationAdvisor} for the given task executor.
	 * @param executor the task executor to use for asynchronous methods
	 * (can be {@code null} to trigger default executor resolution)
	 * @param exceptionHandler the {@link AsyncUncaughtExceptionHandler} to use to
	 * handle unexpected exception thrown by asynchronous method executions
	 * @see AnnotationAsyncExecutionInterceptor#getDefaultExecutor(BeanFactory)
	 */
	@SuppressWarnings("unchecked")
	public AsyncAnnotationAdvisor(@Nullable Executor executor, @Nullable AsyncUncaughtExceptionHandler exceptionHandler) {
		Set<Class<? extends Annotation>> asyncAnnotationTypes = new LinkedHashSet<>(2);
		asyncAnnotationTypes.add(Async.class);
		try {
			asyncAnnotationTypes.add((Class<? extends Annotation>)
					ClassUtils.forName("javax.ejb.Asynchronous", AsyncAnnotationAdvisor.class.getClassLoader()));
		}
		catch (ClassNotFoundException ex) {
			// If EJB 3.1 API not present, simply ignore.
		}
		if (exceptionHandler != null) {
			this.exceptionHandler = exceptionHandler;
		}
		else {
			this.exceptionHandler = new SimpleAsyncUncaughtExceptionHandler();
		}
		// 创建Advice
		this.advice = buildAdvice(executor, this.exceptionHandler);
		// 创建PointCut
		this.pointcut = buildPointcut(asyncAnnotationTypes);
	}

@Aspect的执行机制,及执行过程中,更好理解之前创建的各个类的角色及作用

基础结构类infrastructure class 永远不会被代理,比如org.springframework.transaction.config.internalTransactionAdvisor。
在创建该对象的时候,通过debug,重新理解了BeanFactory的singletonsCurrentlyInCreation这个对象集合所存在的意义。
Q:为什么在实际创建对象getSingleton(beanName, ObjectFactory)之前,要先做标记为已创建该对象的操作。
A:以Spring AOP来说,防止已经创建过的bean对象又被AOP代理的过程中再次创建该对象。

Spring AOP 中的基础数据结构

advisedBeans

private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<Object, Boolean>(256);
存放所有被Spring容器管理的对象,并且判断他们是否需要被Spring AOP所代理。

Advisor在Spring AOP中扮演的角色及作用

Spring AOP 是基于环绕通知around advice来拦截方法传递的,支持各种类型的通知,诸如前置before通知和后置after通知,这两个通知都不需要通过使用拦截器interception来实现。容纳Advice和Pointcut。
==拦截器 Interceptor extends Advice ==

PointcutAdvisor在Spring AOP中扮演的角色及作用

基于切点pointcut驱动的所有通知的父接口。这包含了几乎所有的通知,除了不使用方法级别匹配的引入通知introduction advisors。

AbstractPointcutAdvisor在Spring AOP中扮演的角色及作用

该类的子类返回指定类型的切点pointcut或者通知advisor。

Spring AOP中的编码规范

  1. 用语义代替null值,便于理解代码场景,尽量减少代码中的object == null 这种判断。
/**
	 * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
	 * @param bean the raw bean instance
	 * @param beanName the name of the bean
	 * @param cacheKey the cache key for metadata access
	 * @return a proxy wrapping the bean, or the raw bean instance as-is
	 */
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		// DO_NOT_PROXY 其实就为null。
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

以用户操作日志为例,来说明Spring AOP如何起作用

需求描述:有一个管理系统,我们现在需要对用户的各种操作进行日志记录。首先,联想到的就是利用Spring AOP来完成各种增删改的日志切面。以LoginController的login()为例。
当用户第一次点击登录时,Spring在后台是这样处理的(不包含shiro校验的分析):
调用getBean创建LoginController对象,在创建bean对象的initializeBean中用AnnotationAwareAspectJAutoProxyCreator Bean处理器完成LoginController代理对象的创建。
这个bean后置处理器,找到能够处理LoginController.class的Advisor【怎么去理解Advisor,其实就是包含了切点跟切入方法。所以,一个切面类,有几个切面方法,就有几个对应的Advisor】,在这个过程中,创建了LoginController的代理对象。
当用户再次请求时,走Spring MVC的流程,反射执行方法,注意:执行的是代理对象增强后的login方法。代理对象重写了login方法,当执行的时候,会被拦截。
在这里插入图片描述

总结:

  1. Spring AOP中Advice ,PointCut, Advisor的三者之间的关系:Advisor = Advice + PointCut
  2. 自定义一个基于Spring AOP的Advisor
    • 实现一个继承AbstractPointcutAdvisor的Advisor,如果需要使用IOC容器,外加BeanFactoryAware
    • 实现对应的Advice,通常来说,该Advice,会是一个MethodInterceptor
    • 创建一个ComposabelPointCut
  3. MethodInterceptor 不等于Advice,因为,Advice还包括BeforeAdvice,AfterAdvice,AfterReturningAdvice
  4. @Transactional和@Async,不同之处在于,@Transactional是被AnnotationAwareAspectJAutoProxyCreator处理的,而@Async是被AsyncAnnotationBeanPostProcessor处理的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值