AOP 源码学习笔记

716 阅读8分钟

刚开始看源码,很多地方理解不深,本文适合作为入门教程。欢迎各位大佬指教 : )

零、术语及概念

1.1 Advisor

  • ==Advisor== 是 ==PointCut==、==Advice== 的结合,是 Spring Aop 的顶层抽象。

  • 其继承体系主要有两个 PointCutAdvisorIntroductionAdvisor

  • IntroductionAdvisor:只能应用于类级别的拦截。


一、AOP功能的引入—— AnnotationAwareAspectJAutoProxyCreator

aop 功能由 @EnableAspectJAutoProxy 引入

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
	boolean proxyTargetClass() default false;
	boolean exposeProxy() default false;
}
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
	
	    // 会注册 AnnotationAwareAspectJAutoProxyCreator,见下面代码
		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);
			}
		}
	}
}


@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
    // 注册 AnnotationAwareAspectJAutoProxyCreator
	return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

  aop 的功能主要是由 ==AnnotationAwareAspectJAutoProxyCreator== 提供的,其继承关系图如下:


   可以看出 AnnotationAwareAspectJAutoProxyCreator 的父类有 BeanPoseProcessorBeanPostProcessor 接口方法有 postProcessorAfterInitialization,会在 bean 初始化之后调用。

public interface BeanPostProcessor {
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

二、构建适用于 bean 上的 advisor

整体流程图如下:

由第一节知,入口为 AnnotationAwareAspectJAutoProxyCreator#postProcessorAfterInitailization

AbstractAutoProxyCreator:

=== postProcessAfterInitialization:
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (this.earlyProxyReferences.remove(cacheKey) != bean) {
		    // 此方法主要判断 bean 是否需要被代理
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

=== wrapIfNecessary:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	// 当前 bean 是否在 targetSourcedBeans 缓存中存在(已经被处理过),如果存在直接返回
	// targetSourcedBeans.add 在 beforePostProcessInitialization() 中
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
	// bean 是 aop 基础类 或者 应该跳过
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}
	
	// 关注,见 code1
	// 作用:获取该 bean 的 advisor 或 advice
	// 具体逻辑在 AbstractAdvisorAutoProxyCreator 中
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	
	// 需要对 bean 进行代理
	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;
}

code1 —— Advisor 获取流程 —— AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

// 查找该 bean 上有效的 Advisor
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 此方法在 AnnotationAwareAspectJAutoProxyCreator 中有子类实现
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	
	// 在 advisor 中查找适用于当前 bean 的advisor
	// 见代码段 code2
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	
	// 在拦截器链最前面加 ExposeInvocationInterceptor.ADVISOR 即 DefaultPointcutAdvisor
	extendAdvisors(eligibleAdvisors);
	
	if (!eligibleAdvisors.isEmpty()) {
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	
	return eligibleAdvisors;
}

// AnnotationAwareAspectJAutoProxyCreator 子类具体实现
protected List<Advisor> findCandidateAdvisors() {
    // 获取 advisors,关注
    List<Advisor> advisors = super.findCandidateAdvisors();
    if (this.aspectJAdvisorsBuilder != null) {
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
    return advisors;
}

1. findCandidateAdvisors

   接下来看 findCandidateAdvisors(),==其具体实现在 BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans 中==

protected List<Advisor> findCandidateAdvisors() {
    // 获取 advisors
    List<Advisor> advisors = super.findCandidateAdvisors();
    
    // 为 bean 工厂构建 advisor
    if (this.aspectJAdvisorsBuilder != null) {
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
    return advisors;
}

2. buildAspectJAdvisors

BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors:

public List<Advisor> buildAspectJAdvisors() {
	List<String> aspectNames = this.aspectBeanNames;
	
	/*
	 * this.aspectBeanNames 缓存为空,即未处理过,才执行以下逻辑
	 * 在 postProcessBeforeInstantiation 进入到此方法中时,缓存为 null
	 * 在 postProcessAfterInstantiation 之后的流程中,缓存不为空
	 */
	if (aspectNames == null) {
		synchronized (this) {
			aspectNames = this.aspectBeanNames;
			if (aspectNames == null) {
				List<Advisor> advisors = new ArrayList<>();
				aspectNames = new ArrayList<>();
				
				/*
				 * 参数 Object.class,表示取出所有的 bean。
				 * 此方法非常耗时,所以 spring 在此处设置了缓存机制
				 * 即 this.aspectBeanNames
				 */
				String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
				
				// 紧接着遍历 beanName
				for (String beanName : beanNames) {
					// 跳过不合法的 beanName
					if (!isEligibleBean(beanName)) { continue; }
					
					// 通过 beanName 获取 class 信息
					Class<?> beanType = this.beanFactory.getType(beanName);
					
					if (beanType == null) { continue; }
					
					// 处理标有 AspectJ 注解的类
					if (this.advisorFactory.isAspect(beanType)) {
						// 加入缓存
						aspectNames.add(beanName);
						
						AspectMetadata amd = new AspectMetadata(beanType, beanName);
						if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
							/*
							 * 实际类型是 BeanFactoryAspectInstanceFactory
							 * 会根据 beanName 查找对应 class 属性
							 * 把 beanName,class 封装到 AspectMetadata 中
							 */
							MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
							
							/**
							 * 解析拦截方法,生成增强器
							 *
							 * 利用 factory 中的 beanName, 获取其 class 信息,然后
							 *   1.解析 @pointCut 上的表达式,封装成 AspectJExpressionPointcut
							 *   2.获取 @Before@After 等方法,封装成 Method
							 *   3.把上述参数封装成 InstantiationModelAwarePointcutAdvisorImpl,即 Advisor 的子类
							 * 
							 * 具体实现在 ReflectiveAspectJAdvisorFactory#getAdvisors 中
							 * 为了不影响对整体流程的分析,此方法的具体实现放在文章末尾
							 */
							List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
							
							// 单例直接将解析的增强方法放入缓存
							if (this.beanFactory.isSingleton(beanName)) {
								this.advisorsCache.put(beanName, classAdvisors);
							}
							
							// 不是单例则缓存 factory
							else {
								this.aspectFactoryCache.put(beanName, factory);
							}
							
							advisors.addAll(classAdvisors);
						}
						else {
							if (this.beanFactory.isSingleton(beanName)) {
								throw new IllegalArgumentException("");
							}
							MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
							this.aspectFactoryCache.put(beanName, factory);
							advisors.addAll(this.advisorFactory.getAdvisors(factory));
						}
					}
				}
				this.aspectBeanNames = aspectNames;
				return advisors;
			}
		}
	}
	
	
	if (aspectNames.isEmpty()) {
		return Collections.emptyList();
	}
	List<Advisor> advisors = new ArrayList<>();
	for (String aspectName : aspectNames) {
		List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
		if (cachedAdvisors != null) {
			advisors.addAll(cachedAdvisors);
		}
		else {
			MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
			advisors.addAll(this.advisorFactory.getAdvisors(factory));
		}
	}
	return advisors;
}

2. findAdvisorsThatCanApply

   AopUtils#findAdvisorsThatCanApply

/**
 * @param candidateAdvisors 上一步 findCandidateAdvisor 中返回的,即所有的 Advisor
 * @param clazz beanClass
 */
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();
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor) {
			// already processed
			continue;
		}
		
		// 普通增强 PointcutAdvisor
		if (canApply(candidate, clazz, hasIntroductions)) {
			eligibleAdvisors.add(candidate);
		}
	}
	return eligibleAdvisors;
}

   AopUtils#canApply

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
	if (!pc.getClassFilter().matches(targetClass)) {
		return false;
	}
	
	MethodMatcher methodMatcher = pc.getMethodMatcher();
	if (methodMatcher == MethodMatcher.TRUE) {
		return true;
	}
	
	// AspectJExpressionPointcut,切点表达式的 matcher
	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) {
		    // 如果切点表达式 matcher 不为 null,则用切点表达式匹配
			if (introductionAwareMethodMatcher != null ? introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : methodMatcher.matches(method, targetClass)) {
				return true;
			}
		}
	}
	return false;
}

三、生成代理对象

   继续回到 ==AbstractAutoProxyCreator#wrapIfNecessary==,在此方法中,主要有 2 个重要过程:

  1. 获取 bean 上的 advisor
  2. 以获取到的 advisor 为参数,生成代理对象

  AbstractAutoProxyCreator#wrapIfNecessary:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	// 当前 bean 是否在 targetSourcedBeans 缓存中存在(已经被处理过),如果存在直接返回
	// targetSourcedBeans.add 在 beforePostProcessInitialization() 中
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
	// bean 是 aop 基础类 或者 应该跳过
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}
	
	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;
}

  此方法为 bean 创建代理,对于代理的创建委托给了 proxyFactory 处理,此方法主要做 proxyFactory 的初始化工作。主要有以下几点:

  • 属性拷贝
  • setProxyTargetClass() 来确定代理的方式
  • 添加代理接口
  • 包装 advisor
  • 执行定制函数 customizeProxyFactory()
  • 创建代理
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
	if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
		AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
	}
	
	ProxyFactory proxyFactory = new ProxyFactory();
	proxyFactory.copyFrom(this);
	
	// proxyTargetClass 默认为 false,true 使用 CGLib 代理,false 使用 jdk 动态代理
	if (!proxyFactory.isProxyTargetClass()) {
		// 判断是否基于类代理,即 CGLib 代理
		if (shouldProxyTargetClass(beanClass, beanName)) {
			proxyFactory.setProxyTargetClass(true);
		}else {
		    // 对代理接口做进一步评估,见 code
			evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}
	
	// 把拦截器包装为 advisor,具体见 code
	Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
	
	proxyFactory.addAdvisors(advisors);
	proxyFactory.setTargetSource(targetSource);
	
	//
	customizeProxyFactory(proxyFactory);
	
	proxyFactory.setFrozen(this.freezeProxy);
	
	if (advisorsPreFiltered()) {
		proxyFactory.setPreFiltered(true);
	}
	
	// 调用 getProxy()
	return proxyFactory.getProxy(getProxyClassLoader());
}

code2 —— 构造 advisor —— AbstractAutoProxy#buildAdvisors

   此方法中,把所有的拦截器统一封装成 advisor

protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
	// 解析公共拦截器
	Advisor[] commonInterceptors = resolveInterceptorNames();
	
	List<Object> allInterceptors = new ArrayList<>();
	if (specificInterceptors != null) {
		allInterceptors.addAll(Arrays.asList(specificInterceptors));
		// 判断一下优先级
		if (commonInterceptors.length > 0) {
			if (this.applyCommonInterceptorsFirst) {
				allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
			}
			else {
				allInterceptors.addAll(Arrays.asList(commonInterceptors));
			}
		}
	}

	Advisor[] advisors = new Advisor[allInterceptors.size()];
	for (int i = 0; i < allInterceptors.size(); i++) {
	    // 将拦截器包装成 advisor
	    // DefaultAdvisorAdapterRegistry.wrap()
		advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
	}
	return advisors;
}

   继续看包装流程,this.advisorAdapterRegistry 实际对象为 ==DefaultAdvisorAdapterRegistry==。

DefaultAdvisorAdapterRegistry#wrap:

public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
	if (adviceObject instanceof Advisor) {
		return (Advisor) adviceObject;
	}
	if (!(adviceObject instanceof Advice)) {
		throw new UnknownAdviceTypeException(adviceObject);
	}
	
	Advice advice = (Advice) adviceObject;
	
	/*
	 * 后置通知:AspectJAfterAdvice,前置通知:MethodBeforeAdviceInterceptor
	 * 等都是 MethodInterceptor 的子类
	 */
	if (advice instanceof MethodInterceptor) {
		return new DefaultPointcutAdvisor(advice);
	}
	for (AdvisorAdapter adapter : this.adapters) {
		// Check that it is supported.
		if (adapter.supportsAdvice(advice)) {
			return new DefaultPointcutAdvisor(advice);
		}
	}
	throw new UnknownAdviceTypeException(advice);
}

code3 —— 创建代理 —— ProxyFactory

public Object getProxy(@Nullable ClassLoader classLoader) {
	return createAopProxy().getProxy(classLoader);
}

   先来看 createAopProxy(),其具体实现在 DefaultAopProxyFactory#createAopProxy中:

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	/*
	 * CGLib 代理
	 * optimize:用于控制通过cglib创建的代理是否使用激进的优化策略。除非完全了解AOP如何处理代理优化,
	 * isProxyTargetClass:默认为 false,可以手动配置,为 true 时,强制使用 CGLib 代理
	 * config:ProxyFactory
	 * hasNoUserSuppliedProxyInterfaces: 判断是否实现了接口
	 */
	if (!IN_NATIVE_IMAGE && (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
		Class<?> targetClass = config.getTargetClass();
		if (targetClass == null) {
			throw new AopConfigException("xxx");
		}
		
		/*
		 * 要被代理的对象是接口 || targetClass是Proxy class
		 * 使用 JDK 动态代理
		 */
		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
			return new JdkDynamicAopProxy(config);
		}
		
		return new ObjenesisCglibAopProxy(config);
	}
	else {
		return new JdkDynamicAopProxy(config);
	}
}

   此方法会根据情况选择代理方式:

  • bean 如果实现了接口,默认会选择 jdk 动态代理,但可以通过配置 proxyTargetClass=true 强制使用 CGLib 代理
  • bean 没有实现接口,只能使用 CGLib 代理

四、invoke

1. JdkDynamicAopProxy

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	Object oldProxy = null;
	boolean setProxyContext = false;
	TargetSource targetSource = this.advised.targetSource;
	Object target = null;
	
	try {
		if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
			return equals(args[0]);
		}
		else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
			return hashCode();
		}
		else if (method.getDeclaringClass() == DecoratingProxy.class) {
			return AopProxyUtils.ultimateTargetClass(this.advised);
		}
		else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
			return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
		}
		
		Object retVal;
		if (this.advised.exposeProxy) {
			oldProxy = AopContext.setCurrentProxy(proxy);
			setProxyContext = true;
		}
		
		target = targetSource.getTarget();
		Class<?> targetClass = (target != null ? target.getClass() : null);
		
		// 获取拦截器链,由 advisorChainFactory 完成
		// 见 code
		List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
		if (chain.isEmpty()) {
			Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
			retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
		}
		else {
		    // chain 包装到 MethodInvocation 中
			MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
			// 具体执行分析,见 code
			retVal = invocation.proceed();
		}
		
		Class<?> returnType = method.getReturnType();
		
		if (retVal != null && retVal == target &&
				returnType != Object.class && returnType.isInstance(proxy) &&
				!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
			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()) {
			targetSource.releaseTarget(target);
		}
		if (setProxyContext) {
			AopContext.setCurrentProxy(oldProxy);
		}
	}
}

code4 —— ReflectiveMethodInvocation

public Object proceed() throws Throwable {
    // this.currentInterceptorIndex 初始为 -1
	if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
		return invokeJoinpoint();
	}
	
	// 依此获取 chain 中拦截器,index=0 时为 ExposeInvocationInterceptor
	Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
	
	if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
		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 {
		/*
		 * 在获取 advisor 过程中,会根据不同的通知类型返回不同的实现类,具体可看第五段
		 * 这里会执行对应的实现类的 invoke 方法
		 * 
		 * before: MethodBeforeAdviceInterceptor
		 * after: AspectJAfterAdvice
		 *
		 * @param this 上面的 new ReflectiveMethodInvocation().proceed()
		 */
		return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
	}
}

2. CGLib


   ==前置通知== MethodBeforeAdviceInterceptor:

public Object invoke(MethodInvocation mi) throws Throwable {
	this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
	return mi.proceed();
}

   ==后置通知== AspectJAfterAdvice:

public Object invoke(MethodInvocation mi) throws Throwable {
	try {
	    // 先执行方法本体
		return mi.proceed();
	}finally {
		invokeAdviceMethod(getJoinPointMatch(), null, null);
	}
}

五、Advisor 获取的具体过程

BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors

  主要流程见 code1 中的 2,:

  1. 获取所有的 beanName
  2. 遍历 beanName,找出存在 @AspectJ 注解的 beanName
  3. 对于存在 @AspectJ 注解的 beanName,解析其中的增强方法,如 @After、@Before
  4. 将第 3 步中的结果加入到缓存中

1. ReflectiveAspectJAdvisorFactory#getAdvisors

ReflectiveAspectJAdvisorFactory#getAdvisors:

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
	// 获取到 aspect 切面的 name 及 class
	Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
	String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
	validate(aspectClass);
	
	// 包装此 aspectInstanceFactory,使其只实例化一次
	MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
	
	List<Advisor> advisors = new ArrayList<>();
	// getAdvisorMethods(), 反射获取切面中所有的通知方法,即非 @pointCut 注解标注的方法
	for (Method method : getAdvisorMethods(aspectClass)) {
		// 生成增强器,具体见下面代码
		Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
		if (advisor != null) {
			advisors.add(advisor);
		}
	}
	
	if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
		Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
		advisors.add(0, instantiationAdvisor);
	}
	
	for (Field field : aspectClass.getDeclaredFields()) {
		Advisor advisor = getDeclareParentsAdvisor(field);
		if (advisor != null) {
			advisors.add(advisor);
		}
	}
	return advisors;
}

ReflectiveAspectJAdvisorFactory#getAdvisor:

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) {
	validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
	
	AspectJExpressionPointcut expressionPointcut = getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
	
	if (expressionPointcut == null) { return null; }
	
	// 由 InstantiationModelAwarePointcutAdvisorImpl 统一封装
	return new InstantiationModelAwarePointcutAdvisorImpl(
			expressionPointcut, candidateAdviceMethod, this,
			aspectInstanceFactory, declarationOrderInAspect, aspectName
	);
}

   继续看 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()) {
		// Static part of the pointcut is a lazy type.
		Pointcut preInstantiationPointcut = Pointcuts.union(
				aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
		// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
		// If it's not a dynamic pointcut, it may be optimized out
		// by the Spring AOP infrastructure after the first evaluation.
		this.pointcut = new PerTargetInstantiationModelPointcut(
				this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
		this.lazy = true;
	}
	
	else {
		// A singleton aspect.
		this.pointcut = this.declaredPointcut;
		this.lazy = false;
		
		//
		this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
	}
}

private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {

    // 这里具体实现在 ReflectiveAspectJAdvisorFactory#getAdvice
	Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
	return (advice != null ? advice : EMPTY_ADVICE);
}
/**

   继续看 getAdvice 方法,在此方法中,会根据注解的类型返回不同的实现类

  • AspectJMethodBeforeAdvice
  • AspectJAroundAdvice
  • AspectJAfterAdvice
  • AspectJAfterReturningAdvice

ReflectiveAspectJAdvisorFactory#getAdvice:

public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
		
	Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
	validate(candidateAspectClass);
	
	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();
	}
	if (logger.isDebugEnabled()) {
		logger.debug();
	}
	
	AbstractAspectJAdvice springAdvice;
	switch (aspectJAnnotation.getAnnotationType()) {
		case AtPointcut:
			if (logger.isDebugEnabled()) {
				logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
			}
			return null;
		case AtAround:
			springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
			break;
		case AtBefore:
			springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
			break;
		case AtAfter:
			springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
			break;
		case AtAfterReturning:
			springAdvice = new AspectJAfterReturningAdvice(
					candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
			AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
			if (StringUtils.hasText(afterReturningAnnotation.returning())) {
				springAdvice.setReturningName(afterReturningAnnotation.returning());
			}
			break;
		case AtAfterThrowing:
			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);
	}
	springAdvice.calculateArgumentBindings();
	return springAdvice;
}