Spring源码之AOP(一)——切面的生成

        AOP是一种思想,一种面向切面的变成思想,可以无侵入的增加一些额外的逻辑。提到AOP就会想到动态代理,关于动态代理的应用场景和实现方式(JDK和CGLIB)不是本章重点,大家不熟悉的自行百度,今天我们的主题是Spring的AOP功能,关于AOP涉及到的切面、切点等一大堆我不想一开始就长篇大论抛出来,我会顺着源码的脉络提出来。

        我们知道,Spring是项目运行所需实例(Bean)的一个大管家,它会在容器启动的时候帮我们把所需的类都创建好,使用的时候只需注入就ok了,那么AOP是在什么时候做的呢——它在被代理对象创建完成(实例化)之后才会生成代理对象,因为有了源对象,才能生成代理对象,进行业务增强。

        接下来进入源码,在Bean实例化的核心方法doCreateBean()方法org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// BeanWrapper是实例化之后的对象又做了封装
		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			// TODO 创建实例,重点看
			// 1.实例化factoryMethod方法对应的实例
			// 2.实例化带有@Autowired注解的有参构造函数
			// 3.实例化没有@Autowired注解的有参构造函数
			// 4.实例化无参构造函数
			// 实例化之后堆内存中有了该实例,但是属性却是空的(一个不完整的对象)
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		// 从BeanWrapper中拿真正的实例对象
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					/**
					 * TODO CommonAnnotationBeanPostProcessor支持@PostConstruct、@PreDestroy、@Resource注解
					 *     AutowiredAnnotationBeanPostProcessor支持@Autowired、@Value注解
					 *     收集注解:对类中注解的装配过程
					 *     这个方法是BeanPostProcessor接口的典型运用, 重要程度5,必须看
					 *     收集类中有注解的属性和方法,包装成对象,并将对象加入到容器,并把容器包装成InjectionMetadata对象,并放到缓存中
					 *     缓存是beanName和InjectionMetadata的对应关系,然后通过这个对象可以知道,哪个属性或方法上有注解,为下面的填充做准备
					 */
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			// TODO 添加三级缓存,即执行getEarlyBeanReference(),这里着重理解,助于理解循环依赖,
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			/**
			 * TODO IOC、DI,依赖注入的核心方法,重要程度:5,
			 *  主要是完成@Autowired、@Resource、xml配置方式的依赖注入
			 *  在此之前,堆内存已经有实例,只是属性为空,所以这个方法做的就是属性填充
			 */
			populateBean(beanName, mbd, instanceWrapper);
			/**
			 * TODO Bean实例化+IOC依赖注入完成之后的调用,重要程度:5
			 * 	init-method属性和initializingBean接口方法afterPropertiesSet()调用,@PostConstruct注解方法调用,以及AOP代理对象的生成入口
			 */
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}

    ----省略无关代码----

}

        完成beanDefinition的属性填充之后,进入initializeBean()方法:

	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			// 调用Aware接口方法
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			// 对类中某些特殊方法的调用,比如@PostConstruct,Aware接口,非常重要 重要程度: 5
			// 类似于装饰,如果有需要,在这里将需要操作的bean各种操作后再返回,也可以原封不动返回
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 调用实现了InitializingBean接口的afterPropertiesSet(),init-method属性调用,非常重要,重要程度:5
			// InitializingBean接口的afterPropertiesSet()是在bean实例化之后调用
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			// 和上面的applyBeanPostProcessorsBeforeInitialization()类似,都是BeanPostProcessor的应用
			// 这个地方会生成代理实例,AOP的入口,AOP的实现也是通过埋点来生成的
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

       AOP的入口是在Bean实例化的末尾, 通过BeanPostProcessor 的埋点postProcessAfterInitialization()方法里面进行的:

	// AOP的入口
	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			// 一些validate的框架都是在这调用的
			// 被@Component注解修饰的事件监听在ApplicationListenerDetector中加入到Spring容器中
            // AOP的埋点入口->进入AbstractAutoProxyCreator.postProcessAfterInitialization()方法
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

        当我们通过@EnableAspectJAutoProxy开启AOP功能时,getBeanPostProcessors()方法获取到的BeanPostProcessor类就会多一个AnnotationAwareAspectJAutoProxyCreator。我们先进入它的父类AbstractAutoProxyCreator.postProcessAfterInitialization()方法:

 所属类:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

    /**
	 * TODO 生成当前实例化bean的代理
	 */
	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                // 生成代理的逻辑
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

        我们先看xml标签中AOP功能的实现,它涉及到自定义标签的解析,XML中开启AOP功能,必须要有<aop:aspectj-autoproxy>标签。

进入META-INF目录下的spring-handlers文件:

http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler

        进入AopNamespaceHandler类:

public class AopNamespaceHandler extends NamespaceHandlerSupport {

	@Override
	public void init() {
		// In 2.0 XSD as well as in 2.5+ XSDs
		registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        // AOP对应的标签是这个,它的解析由AspectJAutoProxyBeanDefinitionParser类负责
		registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
		registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());

		// Only in 2.0 XSD: moved to context namespace in 2.5+
		registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
	}

进入AspectJAutoProxyBeanDefinitionParser类:

	// 标签的解析方法
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		// TODO 核心方法
		AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
		extendBeanDefinition(element, parserContext);
		return null;
	}

进入registerAspectJAnnotationAutoProxyCreatorIfNecessary()方法:

所属类:org.springframework.aop.config.AopConfigUtils

	public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			ParserContext parserContext, Element sourceElement) {
		// 注册生成AOP代理类的AutoProxyCreator
		BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
				parserContext.getRegistry(), parserContext.extractSource(sourceElement));
		useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
		registerComponentIfNecessary(beanDefinition, parserContext);
	}

进入registerAspectJAnnotationAutoProxyCreatorIfNecessary()方法:

	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {
		// 把AnnotationAwareAspectJAutoProxyCreator(是AbstractAutoProxyCreator的子类)变成BeanDefinition,让Spring进行管理
		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}

        也是BeanPostProcessor调用的时候,把AnnotationAwareAspectJAutoProxyCreator(AOP的入口类)这个Bean注册到Spring容器,它会去解析@Aspect注解类中定义的切面,创建代理对象,我们会在后面的源码中看到。

        看一下AnnotationAwareAspectJAutoProxyCreator的结构,它继承自AspectJAwareAdvisorAutoProxyCreator,AspectJAwareAdvisorAutoProxyCreator又继承了AbstractAdvisorAutoProxyCreator抽象类,它的父类是AbstractAutoProxyCreator 。我们重点介绍一下这两个类:

        AbstractAdvisorAutoProxyCreator

        AbstractAdvisorAutoProxyCreator非常强大以及重要,Spring容器中如果存在这个类型的
Bean,就相当于开启了AOP。AbstractAdvisorAutoProxyCreator实际上就是一个
BeanPostProcessor,在创建某个Bean时,就会进入到对应的方法,比如:在某个Bean初始化之后,会调用wrapIfNecessary()方法进行AOP,底层逻辑是:
AbstractAdvisorAutoProxyCreator会找到所有的Advisor,然后判断当前的Bean是否存在某个
Advisor与之匹配(根据Pointcut),如果匹配就表示当前这个Bean有对应的切面逻辑,需要进行
AOP,需要产生一个代理对象。另外,
Spring事务InfrastructureAdvisorAutoProxyCreator也是通过继承该类实现的。

        AbstractAutoProxyCreator

         AbstractAutoProxyCreator 继承ProxyProcessorSupport实现了SmartInstantiationAwareBeanPostProcessor和BeanFactoryAware接口。

        SmartInstantiationAwareBeanPostProcessor又实现了InstantiationAwareBeanPostProcessor接口,实现了InstantiationAwareBeanPostProcessor的接口会在容器初始化完成以后执行before和after方法,BeanFactoryAware接口的子类可以拿到spring的 BeanFactory的,也就是所有bean的对象。

        AbstractAutoProxyCreator 里面有上面我们看到的生成AOP的逻辑postProcessAfterInitialization()方法。如果想实现自定义的代理逻辑,可以继承该抽象类,Seta中@GlobalTransactional注解就是。

        另外,我们用注解@EnableAspectJAutoProxy开启AOP功能,和<aop:aspectj-autoproxy>标签的作用类似,它会在Spring的容器中注册一个组件,相当于@Import(AnnotationAwareAspectJAutoProxyCreator.class),通过AspectJAutoProxyRegistrar类,将代理入口类AnnotationAwareAspectJAutoProxyCreator实例化,才会有这个入口类,看一下该注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	boolean proxyTargetClass() default false;

	boolean exposeProxy() default false;

}

         如果某个功能想通过注解导入进来,可以通过@Import注解,实现ImportBeanDefinitionRegistrar接口:

    // 重写该方法
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 把AOP的入口类实例化,通过registerAspectJAnnotationAutoProxyCreatorIfNecessary方法变成BeanDefinition
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}

         也是通过AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry)方法把变AnnotationAwareAspectJAutoProxyCreator成BeanDefinition,和自定义标签解析殊途同归。

        回到AbstractAutoProxyCreator类的postProcessAfterInitialization()方法:

    /**
	 * TODO 生成当前实例化bean的代理
	 */
	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			// earlyProxyReferences是一个ConcurrentHashMap,里面存放的是已经生成的代理
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				// 生成当前实例化bean的代理对象**
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

 这个earlyProxyReferences是一个ConcurrentHashMap<>(16),里面存放的是已经生成的代理(三级缓存可能会提前生成代理),如果有不会重复生成。

Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);

         如果没有,就会进入下面的wrapIfNeseessary()方法,该方法里面包含了真正生成代理对象的逻辑。这个入口,是为了给普通bean能够生成代理用的,是spring最常见并且使用最多的入口。

        下面我们着重看一下wrapIfNecessary()方法:

        所属类:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		// advicedBeans表示已经判断过的bean,false表示此Bean不需要进行AOP,直接返回
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		// 当前正在创建的Bean不用进行AOP,比如切面Bean
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		// 找切面的过程(判断当前实例化的bean是否有切面,如果有则将切面返回)*****
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		// 如果有切面,则生成bean的代理
		if (specificInterceptors != DO_NOT_PROXY) {
			// advisedBeans记录了某个Bean已经进行过AOP了
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			// 创建代理,把被代理对象bean的实例封装到SingletonTargetSource中,生成当前实例化bean的代理对象*****
			// 传入的bean是被代理实例,SingletonTargetSource持有了被代理实例的引用(一级缓存单例池中存的就是代理对象)
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			// 将代理对象返回
			return proxy;
		}
		// 没有代理的情况,就是false
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

        上面方法参数中的bean就是正在实例化的Bean,它是从AOP的入口类中传过来的,如果需要被代理,就对它进行包装(代理)。另外,多说一句,一级缓存singletonObjects单例池中存的就是代理对象。

        上面这个方法主要做了两件事:1.找切面;2.创建代理,本章先看第一个:

找切面:

        切面是什么:一类功能的增强,如:日志功能、事务功能、缓存功能,spring中切面封装类为Advisor,必须要有PointCut(对什么类起作用)和Advice(起什么作用),在Spring实例化的过程中,为了便于理解,我们可以把它一种特殊的Bean

PointCut:又叫切点,作用是匹配、拦截,一般为@Pointcut注解的方法;

Advice:增强,具体增强的代码(承载了一些增强的逻辑),如带有@Around、@Before、@After注解的方法。

举例:

@Aspect
public class SysLogAspect {

    /**
     * Pointcut:作用范围,凡是带有@LogAnnotation注解的方法都进行增强
     */
    @Pointcut("@annotation(cn.baec.common.aop.annotation.LogAnnotation)")
    public void logPointCut() {
    }

    /**
     * Advice:如何增强,方法执行时增加日志打印功能
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        // 执行方法
        Object result = point.proceed();
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;

        // 记录日志
        try {
            printSysLog(point, result, time);
        } catch (Exception e) {
            log.error("接口异常信息:{}", e);
        }
        return result;
    }

进入子类的getAdvicesAndAdvisorsForBean()方法看找切面的逻辑:

所属类:org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator

	protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
		// 找到合格的切面***
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}

	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		// 找到候选的切面,就是寻找带有@Aspect注解的过程,把带有@Aspect的类封装成Advisor返回
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		// 判断候选的切面是否作用在当前beanClass上面,就是一个匹配的过程
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		// 针对有@Aspect注解的类添加一个默认的切面--->DefaultPointcutAdvisor,解决参数传递问题
		// 进入AspectJAwareAdvisorAutoProxyCreator类的extendAdvisors()方法
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			// 对有@Order、@Priority注解的类进行排序
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

        上面的方法分两步:第一,找候选切面;第二,匹配(拦截类和方法),Pointcut的作用就是匹配、拦截,所以一定会有ClassFilter(拦截类),MethodMather(匹配方法)这两个元素。

        一、先看本类的findAdvisorBeans()方法,寻找带有@Aspect注解的类,找到候选切面,封装成Advisor:

	protected List<Advisor> findCandidateAdvisors() {
		Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
		return this.advisorRetrievalHelper.findAdvisorBeans();
	}

 进入findAdvisorBeans()方法:

所属类:org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper

	public List<Advisor> findAdvisorBeans() {
		// Determine list of advisor bean names, if not cached already.
		String[] 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!
			// 找到所有实现Advisor接口的类的名称,可以实现Advisor接口实现自定义切面
			advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
					this.beanFactory, Advisor.class, true, false);
			this.cachedAdvisorBeanNames = advisorNames;
		}
		if (advisorNames.length == 0) {
			return new ArrayList<>();
		}

		List<Advisor> advisors = new ArrayList<>();
		// 然后根据名称找到类加入容器
		for (String name : advisorNames) {
			if (isEligibleBean(name)) {
				if (this.beanFactory.isCurrentlyInCreation(name)) {
					if (logger.isTraceEnabled()) {
						logger.trace("Skipping currently created advisor '" + name + "'");
					}
				}
				else {
					try {
						advisors.add(this.beanFactory.getBean(name, Advisor.class));
					}

        ----省略无关代码----

 如果是通过@Aspect注解开启切面,会进入到AbstractAdvisorAutoProxyCreator的子类AnnotationAwareAspectJAutoProxyCreator的findCandidateAdvisors()方法:

所属类:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator

	// 找到候选的切面,就是寻找有@Aspect注解的过程,封装成Advisor返回
	@Override
	protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		// 先找到所有Advisor类型的Bean
		List<Advisor> advisors = super.findCandidateAdvisors();
		// Build Advisors for all AspectJ aspects in the bean factory.
		// 再从所有切面中解析得到Advisor对象
		if (this.aspectJAdvisorsBuilder != null) {
			// 创建候选的切面,对有@Aspect注解的类进行处理(包装Advice和Pointcut,还有切面的排序)****
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}

 进入核心方法buildAspectJAdvisors()创建切面Advisor对象:

所属类:org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder

public List<Advisor> buildAspectJAdvisors() {
		List<String> aspectNames = this.aspectBeanNames;

		if (aspectNames == null) {
			synchronized (this) {
				aspectNames = this.aspectBeanNames;
				if (aspectNames == null) {
					List<Advisor> advisors = new ArrayList<>();
					aspectNames = new ArrayList<>();
					// 获取Spring容器中所有实例的beanName
					String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
							this.beanFactory, Object.class, true, false);
					for (String beanName : beanNames) {
						if (!isEligibleBean(beanName)) {
							continue;
						}
						// We must be careful not to instantiate beans eagerly as in this case they
						// would be cached by the Spring container but would not have been weaved.
						// 首先拿到实例的类型
						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负责获取有@Aspect注解的实例
								MetadataAwareAspectInstanceFactory factory =
										new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
								// 创建切面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);
							}
							

            ----省略无关代码----

进入创建切面Advisor对象getAdvisors(factory)方法:

所属类:org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory

	public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
		// 从工厂中获取有@Aspect注解的类的反射对象Class
		Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		// 从工厂中获取有@Aspect注解的类的名称
		String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
		validate(aspectClass);

		// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
		// so that it will only instantiate once.
		// 创建工厂的装饰类,获取实例(只会获取一次)
		MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
				new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

		List<Advisor> advisors = new ArrayList<>();
		// 这里循环没有@Pointcut注解的方法,扫描有@Before、@Around、@After注解的方法,并进行排序,getAdvisorMethods()->
		for (Method method : getAdvisorMethods(aspectClass)) {
			// 获取Advisor*****(只要是有@Before、@After等注解的方法,它们分别和带有@Pointcut注解的方法组合,生成各自Advisor类)
			Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}

		// If it's a per target aspect, emit the dummy instantiating aspect.
		if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
			Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
			advisors.add(0, instantiationAdvisor);
		}

		// Find introduction fields.
		// 判断属性上是否有引介注解
		for (Field field : aspectClass.getDeclaredFields()) {
			Advisor advisor = getDeclareParentsAdvisor(field);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}

		return advisors;
	}

先进入本类的getAdvisorMethods()方法:

	private List<Method> getAdvisorMethods(Class<?> aspectClass) {
		final List<Method> methods = new ArrayList<>();
		// 排除有@Pointcut注解的方法
		ReflectionUtils.doWithMethods(aspectClass, method -> {
			// Exclude pointcuts
			if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
				// methods就是存放没有@Pointcut注解的方法
				methods.add(method);
			}
		}, ReflectionUtils.USER_DECLARED_METHODS);
		if (methods.size() > 1) {
			// 按照注解先后顺序+自然顺序排序
			methods.sort(METHOD_COMPARATOR);
		}
		return methods;
	}

        再进入本类的getAdvisor(),根据方法生成Advisor:

	public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
			int declarationOrderInAspect, String aspectName) {

		validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
		// 获取AspectJExpressionPointcut对象,从注解中获取表达式
		// candidateAdviceMethod就是有@Before、@After注解的方法
		AspectJExpressionPointcut expressionPointcut = getPointcut(
				candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
		if (expressionPointcut == null) {
			return null;
		}
		// 创建真正的Advisor切面类,里面有pointcut和advice***进入InstantiationModelAwarePointcutAdvisorImpl的构造方法
		// expressionPointcut是pointcut,candidateAdviceMethod是advice
		return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
				this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
	}

        创建真正的切面类是在InstantiationModelAwarePointcutAdvisorImpl的构造方法中,该类实现了InstantiationModelAwarePointcutAdvisor接口,每个Advisor会返回一个InstantiationModelAwarePointcutAdvisorImpl实例。

	public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
			Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

		this.declaredPointcut = declaredPointcut;
		this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
		this.methodName = aspectJAdviceMethod.getName();
		this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
		this.aspectJAdviceMethod = aspectJAdviceMethod;
		this.aspectJAdvisorFactory = aspectJAdvisorFactory;
		this.aspectInstanceFactory = aspectInstanceFactory;
		this.declarationOrder = declarationOrder;
		this.aspectName = aspectName;

		if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
            ----省略无关代码----
		}
		else {
			// A singleton aspect.
			this.pointcut = this.declaredPointcut;
			this.lazy = false;
			// 创建advice对象***
			this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
		}
	}

  进入instantiateAdvice()方法:

所属类:springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl

	private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
		// 创建Advice对象,调用到ReflectiveAspectJAdvisorFactory.getAdvice()方法
		Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
				this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
		return (advice != null ? advice : EMPTY_ADVICE);
	}

        创建Advisor切面类,必须要有PointCut(对什么类起作用)和Advice(起什么作用)这两个角色,比如:

@Test
    public void testSpringProxy() {
        GoodsService target = new GoodsService();

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(target);
        proxyFactory.addAdvisor(new PointcutAdvisor() {
            @Override
            public Pointcut getPointcut() {
                return new StaticMethodMatcherPointcut() {
                    @Override
                    public boolean matches(Method method, Class<?> targetClass) {
                        return method.getName().equals("test");
                    }
                };
            }

            @Override
            public Advice getAdvice() {
                // 导org.aopalliance.intercept.MethodInterceptor
                return new MethodInterceptor() {
                    @Override
                    public Object invoke(MethodInvocation invocation) throws Throwable {
                        System.out.println("before...");
                        // 执行被代理方法
                        Object result = invocation.proceed();
                        System.out.println("after...");
                        return result;
                    }
                };
            }

            @Override
            public boolean isPerInstance() {
                return false;
            }
        });

        // 动态代理所创建出来的UserService对象
        GoodsService goodsService = (GoodsService) proxyFactory.getProxy();
        // 执行这个userService的test方法时,就会额外会执行一些其他逻辑
        goodsService.test();
    }

        代理对象在执行时先调用Advisor接口实例的getAdvice()方法:

所属类:springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl

    @Override	
    public synchronized Advice getAdvice() {
		if (this.instantiatedAdvice == null) {
			this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
		}
		return this.instantiatedAdvice;
	}

         然后,会调用到instantiateAdvice(),InstantiationModelAwarePointcutAdvisorImpl类的构造方法else分支中的instantiateAdvice()方法:

	private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
		// 创建Advice对象,调用到ReflectiveAspectJAdvisorFactory.getAdvice()方法
		Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
				this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
		return (advice != null ? advice : EMPTY_ADVICE);
	}

        接下来,会解析创建来的Method上面有哪种类型的注解,创建对应的Advice:

        所属类:org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory

    // 获取Advice方法***(candidateAdviceMethod是有注解的方法)
	@Override
	@Nullable
	public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
		// 获取有@Aspect注解的类
		Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		validate(candidateAspectClass);
		// 找到candidateAdviceMethod方法上面的注解,并且包装成AspectJAnnotation对象
		AspectJAnnotation<?> aspectJAnnotation =
				AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
		if (aspectJAnnotation == null) {
			return null;
		}

		// If we get here, we know we have an AspectJ method.
		// Check that it's an AspectJ-annotated class
		if (!isAspect(candidateAspectClass)) {
			throw new AopConfigException("Advice must be declared inside an aspect type: " +
					"Offending method '" + candidateAdviceMethod + "' in class [" +
					candidateAspectClass.getName() + "]");
		}

		if (logger.isDebugEnabled()) {
			logger.debug("Found AspectJ method: " + candidateAdviceMethod);
		}

		AbstractAspectJAdvice springAdvice;
		// 根据不同的注解类型创建不同的advice实例***
		switch (aspectJAnnotation.getAnnotationType()) {
			case AtPointcut:
				if (logger.isDebugEnabled()) {
					logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
				}
				return null;
			case AtAround:
				// 环绕通知,实现了MethodInterceptor接口
				springAdvice = new AspectJAroundAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtBefore:
				// 前置通知,实现了MethodBeforeAdvice接口,没有实现MethodInterceptor接口
				springAdvice = new AspectJMethodBeforeAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtAfter:
				// 后置通知,实现了MethodInterceptor接口
				springAdvice = new AspectJAfterAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtAfterReturning:
				// 结果通知,实现了AfterReturningAdvice接口,没有实现MethodInterceptor接口
				springAdvice = new AspectJAfterReturningAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
				if (StringUtils.hasText(afterReturningAnnotation.returning())) {
					springAdvice.setReturningName(afterReturningAnnotation.returning());
				}
				break;
			case AtAfterThrowing:
				// 异常通知,实现了MethodInterceptor接口
				springAdvice = new AspectJAfterThrowingAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
				if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
					springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
				}
				break;
			default:
				throw new UnsupportedOperationException(
						"Unsupported advice type on method: " + candidateAdviceMethod);
		}

		// Now to configure the advice...
		springAdvice.setAspectName(aspectName);
		springAdvice.setDeclarationOrder(declarationOrder);
		String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
		if (argNames != null) {
			springAdvice.setArgumentNamesFromStringArray(argNames);
		}
		// 计算argNames和类型的对应关系
		springAdvice.calculateArgumentBindings();

		return springAdvice;
	}

        在这里,五种不同的通知都实现了Advice接口,但是有些差异,AspectJAroundAdvice、AspectJAfterAdvice、AspectJAfterThrowingAdvice实现了MethodInterceptor接口:

图片

         另外两个类:AspectJMethodbeforeAdvice和AspectJAfterReturningAdvice没有实现上面的接口,它们俩继承了AbstractAspectJAdvice抽象类。

        以AspectJMethodBeforeAdvice类为例,进去看一下:

public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable {

	/**
	 * @param aspectJBeforeAdviceMethod 有@Before注解的Method对象
	 * @param pointcut @Before所对应的Pointcut,表示当前Advice所对应的切点
	 * @param aif
	 */
	public AspectJMethodBeforeAdvice(
			Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {

		super(aspectJBeforeAdviceMethod, pointcut, aif);
	}

	// 代理对象执行时就会执行该方法
	@Override
	public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
		invokeAdviceMethod(getJoinPointMatch(), null, null);
	}

	@Override
	public boolean isBeforeAdvice() {
		return true;
	}

	@Override
	public boolean isAfterAdvice() {
		return false;
	}

}

         进入invokeAdviceMethod()方法:

	protected Object invokeAdviceMethod(
			@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex)
			throws Throwable {
        // 进入invokeAdviceMethodWithGivenArgs()方法
		return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
	}

	protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
		Object[] actualArgs = args;
		// aspectJAdviceMethod是@Before修饰的方法
		if (this.aspectJAdviceMethod.getParameterCount() == 0) {
			actualArgs = null;
		}
		try {
			// 反射调用aspectJAdviceMethod方法
			ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
			// TODO AopUtils.invokeJoinpointUsingReflection
			// this.aspectInstanceFactory.getAspectInstance()指切面Bean的实例,actualArgs为方法参数,执行对应方法
			return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
		}
		catch (IllegalArgumentException ex) {
			throw new AopInvocationException("Mismatch on arguments to advice method [" +
					this.aspectJAdviceMethod + "]; pointcut expression [" +
					this.pointcut.getPointcutExpression() + "]", ex);
		}
		catch (InvocationTargetException ex) {
			throw ex.getTargetException();
		}
	}

        需要注意的是,MethodInterceptor接口中有invoke()方法,切面功能增强的代码会调到下面,以@Around注解的解析类AspectJAroundAdvice为例,它实现了MethodInterceptor接口,我们进去看一下:

public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {

    ----省略无关代码----

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		if (!(mi instanceof ProxyMethodInvocation)) {
			throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
		}
		ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
		ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
		JoinPointMatch jpm = getJoinPointMatch(pmi);
		return invokeAdviceMethod(pjp, jpm, null, null);
	}

}

     最终增强的逻辑就是invoke()方法,到此,找候选切面类的过程完成,简单总结一下这个过程:

1. 自定义类实现Advisor接口,并且在类中定义自己的Pointcut和Advice;

2. 解析有@Aspect注解的类,解析有@Before、@After等注解的方法,创建Advice对象,通过注解中配置的value值,创建Pointcut对象,最终根据创建的Advice和Pintcut对象,创建Advisor对象。

        找到Advisor切面类,回到AbstractAdvisorAutoProxyCreator的findEligibleAdvisors()方法,进入匹配过程,判断候选的切面是否作用在当前beanClass上面;

二、进入findAdvisorsThatCanApply()方法:

所属类:org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator

	protected List<Advisor> findAdvisorsThatCanApply(
			List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

		ProxyCreationContext.setCurrentProxiedBeanName(beanName);
		try {
			// 看看当前类是否在这些切面的Pointcut中,调用类和方法的match()过程,找到后返回切面
			return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
		}
		finally {
			ProxyCreationContext.setCurrentProxiedBeanName(null);
		}
	}

 进入findAdvisorsThatCanApply()方法:

所属类:org.springframework.aop.support.AopUtils

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
		if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		List<Advisor> eligibleAdvisors = new ArrayList<>();
		for (Advisor candidate : candidateAdvisors) {
			// 如果是引介切面并且匹配
			if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
				eligibleAdvisors.add(candidate);
			}
		}
		boolean hasIntroductions = !eligibleAdvisors.isEmpty();
		// 类匹配和方法匹配(调用pointcut中的ClassFilter和MethodMatcher的match()的过程)
		for (Advisor candidate : candidateAdvisors) {
			if (candidate instanceof IntroductionAdvisor) {
				// already processed
				continue;
			}
			// Advisor和当前的Bean进行匹配****进入canApply()方法->
			if (canApply(candidate, clazz, hasIntroductions)) {
                // 匹配成功,将切面Advisor返回
				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);
		}
		// 会进入这里,调用下面的canApply()方法***
		else if (advisor instanceof PointcutAdvisor) {
			PointcutAdvisor pca = (PointcutAdvisor) advisor;
			// 获取表达式匹配类和方法,返回true表示当前实例化的bean和advisor是匹配的,也就是这个bean有切面
			// pca.getPointcut()方法表示从PointcutAdvisor拿到Pointcut实例
			return canApply(pca.getPointcut(), targetClass, hasIntroductions);
		}
		else {
			// It doesn't have a pointcut so we assume it applies.
			return true;
		}
	}

         在spring中,通过表达式

@Pointcut("execution(public * com.kieasar.cache.service.TestService.*(..))")

具体匹配某个类,execution只是其中一种,还有:

图片

        所以,除了类匹配之外,还需要方法匹配,所以需要先匹配类,再匹配方法。 进入canApply()方法,pc就是Advisor中的Pointcut,如果两个都能匹配则返回true, 表示切面拦截到了这个类,这个类有切面。自定义的Pointcut的matches()就是在这里执行 。

        所属类:org.springframework.aop.support.AopUtils

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
		Assert.notNull(pc, "Pointcut must not be null");
		// 调用classFilter的matches()方法,判断targetClass是否和当前Pointcut匹配,
        // 调用aop.aspectj.AspectJExpressionPointcut.matches(java.lang.Class<?>)方法**
		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) :
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}

		return false;
	}

  进入AspectJExpressionPointcut类的matches(java.lang.Class<?>)方法,看具体的匹配过程:

	public boolean matches(Class<?> targetClass) {
		// 根据@Around("pc()")配置中的pc找到@Pointcu注解对应的方法,从而找到Pointcut表达式
		PointcutExpression pointcutExpression = obtainPointcutExpression();
		try {
			try {
				// 根据表达式匹配类,看目标类是否在表达中包含的范围
				return pointcutExpression.couldMatchJoinPointsInType(targetClass);
			}
			catch (ReflectionWorldException ex) {
				logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex);
				// Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
				PointcutExpression fallbackExpression = getFallbackPointcutExpression(targetClass);
				if (fallbackExpression != null) {
					return fallbackExpression.couldMatchJoinPointsInType(targetClass);
				}
			}
		}
		catch (Throwable ex) {
			logger.debug("PointcutExpression matching rejected target class", ex);
		}
		return false;
	}

三、进入extendAdvisors()方法:

所属类:org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator

	protected void extendAdvisors(List<Advisor> candidateAdvisors) {
		// 对有@Aspect注解的类添加默认的切面DefaultPointcutAdvisor
		AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
	}

 进入makeAdvisorChainAspectJCapableIfNecessary()方法:

所属类:org.springframework.aop.aspectj.AspectJProxyUtils

	public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
		// Don't add advisors to an empty list; may indicate that proxying is just not required
		if (!advisors.isEmpty()) {
			boolean foundAspectJAdvice = false;
			for (Advisor advisor : advisors) {
				// Be careful not to get the Advice without a guard, as this might eagerly
				// instantiate a non-singleton AspectJ aspect...
				// 判断是否为带有@Aspect注解的类
				if (isAspectJAdvice(advisor)) {
					foundAspectJAdvice = true;
					break;
				}
			}
			// 判断是否包含默认的切面类DefaultPointcutAdvisor,ExposeInvocationInterceptor包括了链式调用的逻辑(利用了threadLocal)
			if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
				// 如果不包含就在Advisor集合的第一个位置添加DefaultPointcutAdvisor元素
				advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
				return true;
			}
		}
		return false;
	}

        我们看一下 ExposeInvocationInterceptor类,它实现了MethodInterceptor接口,在该类中实现了链式调用的逻辑,通过threadLocal来维护AOP调用链中的MethodInvocation 对象,我们也可以通过该工具类获取调用的入参、方法、对象等信息。

public final class ExposeInvocationInterceptor implements MethodInterceptor, PriorityOrdered, Serializable {

	/** Singleton instance of this class. */
	public static final ExposeInvocationInterceptor INSTANCE = new ExposeInvocationInterceptor();

	/**
	 * Singleton advisor for this class. Use in preference to INSTANCE when using
	 * Spring AOP, as it prevents the need to create a new Advisor to wrap the instance.
	 */
	public static final Advisor ADVISOR = new DefaultPointcutAdvisor(INSTANCE) {
		@Override
		public String toString() {
			return ExposeInvocationInterceptor.class.getName() +".ADVISOR";
		}
	};

	private static final ThreadLocal<MethodInvocation> invocation =
			new NamedThreadLocal<>("Current AOP method invocation");


	/**
	 * 从threadLocal中获取当前AOP中的MethodInvocation对象
	 */
	public static MethodInvocation currentInvocation() throws IllegalStateException {
		MethodInvocation mi = invocation.get();
		if (mi == null) {
			throw new IllegalStateException(
					"No MethodInvocation found: Check that an AOP invocation is in progress and that the " +
					"ExposeInvocationInterceptor is upfront in the interceptor chain. Specifically, note that " +
					"advices with order HIGHEST_PRECEDENCE will execute before ExposeInvocationInterceptor! " +
					"In addition, ExposeInvocationInterceptor and ExposeInvocationInterceptor.currentInvocation() " +
					"must be invoked from the same thread.");
		}
		return mi;
	}


	// 用代理对象调用advice,最终会进入这里,把MethodInvocation放到threadLocal中,然后进行火炬传递
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		MethodInvocation oldInvocation = invocation.get();
		invocation.set(mi);
		try {
			// 链式调用,火炬传递
			return mi.proceed();
		}
		finally {
			invocation.set(oldInvocation);
		}
	}

	@Override
	public int getOrder() {
		return PriorityOrdered.HIGHEST_PRECEDENCE + 1;
	}

        总结一下上面的过程:

  • Bean的实例化;
  • 找出所有的切面Bean;
  • 遍历切面中的每个方法,看是否写了@Before、@After等注解;
  • 如果写了,则判断所对应的Pointcut是否和当前Bean对象的类是否匹配;
  • 如果匹配则表示当前Bean对象有匹配的的Pointcut,则通过ProxyFactory生成代理对象。

        总之就是,在Bean的实例化完成之后,调用BeanPostProcessor(AbstractAutoProxyCreator实现BeanPostProcessor接口)的postProcessAfterInitialization()方法,检查是否需要生成代理(先找切面,再匹配),现在切面找到了,下一章进入生成代理的环节。

 

猜你喜欢

转载自blog.csdn.net/qq_40213907/article/details/120215184