首页 > 技术文章 > 【spring】AOP源码分析

zfcq 2022-03-09 00:37 原文

AOP简单介绍

  • 本文源码基于spring-framework-5.3.10。
  • AOP表示面向切面编程,是一种编程思想。

AOP中的一些概念

  • Aspect:表示切面,比如被@Aspect注解的类就是切面,可以在切面中去定义Pointcut、Advice等等。
  • Join point:表示连接点,表示一个程序在执行过程中的一个点,比如一个方法的执行,比如一个异常的处理,在Spring AOP中,一个连接点通常表示一个方法的执行。
  • Advice:表示通知,表示在一个特定连接点上所采取的动作。Advice分为不同的类型,在很多AOP框架中,包括Spring,会用Interceptor拦截器来实现Advice,并且在连接点周围维护一个Interceptor链。
  • Pointcut:表示切点,用来匹配一个或多个连接点,Advice与切点表达式是关联在一起的,Advice将会执行在和切点表达式所匹配的连接点上。
  • Introduction:可以使用@DeclareParents来给所匹配的类添加一个接口,并指定一个默认实现。
  • Target object:目标对象,被代理对象。
  • AOP proxy:表示代理工厂,用来创建代理对象的,在Spring Framework中,要么是JDK动态代理,要么是CGLIB代理。
  • Weaving:表示织入,表示创建代理对象的动作,这个动作可以发生在编译时期(比如Aspejctj),或者运行时,比如Spring AOP。

Advice在Spring AOP中对应API

  • @Before:AspectJMethodBeforeAdvice,实际上就是一个MethodBeforeAdvice。
  • @AfterReturning:AspectJAfterReturningAdvice,实际上就是一个AfterReturningAdvice。
  • @AfterThrowing:AspectJAfterThrowingAdvice,实际上就是一个MethodInterceptor。
  • @After:AspectJAfterAdvice,实际上就是一个MethodInterceptor。
  • @Around:AspectJAroundAdvice,实际上就是一个MethodInterceptor。

AOP整体流程

  • 实例化前,会判断是否对当前beanName设置了TargetSource,可以通过CustomTargetSourceCreators来设置,如果设置了则直接针对所设置的TargetSource进行AOP,得到代理对象后直接返回,不会经过后续的生命周期了。
  • 实例化,得到原始对象。
  • 给原始对象填充属性。
  • 初始化前。
  • 初始化。
  • 初始化后,这里会开始进行AOP。
  • 先判断当前Bean是不是要进行AOP,比如当前Bean的类型是PointCut、Advice、Advisor等就不需要进行AOP。
  • 筛选出和当前Bean所匹配的Advice、Advisor。
  • 基本Bean的原始对象和所匹配的Advice、Advisor创建代理对象,并返回。

创建代理对象的流程。

  • 构造一个ProxyFactory。
  • 配置ProxyFactory。
  • 将commonInterceptors和specificInterceptors整合再一起。

生成代理对象流程

  • 构造Enhancer对象。
  • 设置DynamicAdvisedInterceptor为Callback。
  • 所以代理对象执行方法时就会经过DynamicAdvisedInterceptor。

代理对象执行方法的流程

  • 根据当前所调用的方法和对应的类筛选对应的Advisor。
  • 获取Advisor中的Advice,并封装为MethodInterceptor。
  • 将得到的所有匹配的MethodInterceptor组合成List
  • 将代理对象、被代理对象、当前正在执行的被代理类中的方法对象、方法参数、被代理的类、chain、当前正在执行的代理类中的方法对象整合成一个CglibMethodInvocation对象。
  • 调用CglibMethodInvocation对象的proceed()方法。
  • 开始执行MethodInterceptor,不同类型的MethodInterceptor执行逻辑会有差异。
  • MethodInterceptor执行完了之后(调用链的总结,所有调用链加载完成的时候),会执行被代理对象的对应的方法对象,也就是执行被代理对象中对应的方法,也就是业务方法。

ProxyFactory选择cglib或jdk动态代理原理

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

	/**
	 * 如果ProxyFactory的isOptimize为true,Spring认为cglib比jdk动态代理要快。
	 * 或者isProxyTargetClass为true,
	 * 或者被代理对象没有实现接口,
	 * 或者只实现了SpringProxy这个接口,
	 * 那么则利用Cglib进行动态代理,但如果被代理类是接口,或者被代理类已经是进行过JDK动态代理而生成的代理类了则只能进行JDK动态代理
	 * 其他情况都会进行JDK动态代理,比如被代理类实现了除SpringProxy接口之外的其他接口
	 */
	@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

		// 是不是在GraalVM虚拟机上运行
		// config.isOptimize():使用proxyFactory.setOptimize(true)进行设置,默认为false。
		// config.isProxyTargetClass():使用proxyFactory.setProxyTargetClass(true)进行设置,默认为false。
		// hasNoUserSuppliedProxyInterfaces(config):使用proxyFactory.addInterface()便会返回false。
		if (!NativeDetector.inNativeImage() &&
				(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {

			// 获取被代理的对象
			Class<?> targetClass = config.getTargetClass();
			// 被代理的对象为空,抛异常
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}

			// 被代理的对象是个接口或者是个jdk动态代理产生的代理对象
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				// 使用jdk的动态代理
				return new JdkDynamicAopProxy(config);
			}

			// 使用cglib动态代理
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			// 使用jdk的动态代理
			return new JdkDynamicAopProxy(config);
		}
	}
	
	......
}

cglib动态代理的实现逻辑

/**
 * cglib动态代理实现逻辑
 */
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
	if (logger.isTraceEnabled()) {
		logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
	}

	try {
		// 被代理的类
		Class<?> rootClass = this.advised.getTargetClass();
		Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

		Class<?> proxySuperClass = rootClass;
		// 如果被代理类本身就已经是Cglib所生成的代理类了
		if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
			// 获取真正的被代理类
			proxySuperClass = rootClass.getSuperclass();
			// 获取被代理类所实现的接口
			Class<?>[] additionalInterfaces = rootClass.getInterfaces();
			for (Class<?> additionalInterface : additionalInterfaces) {
				this.advised.addInterface(additionalInterface);
			}
		}

		// Validate the class, writing log messages as necessary.
		validateClassIfNecessary(proxySuperClass, classLoader);

		// Configure CGLIB Enhancer...
		Enhancer enhancer = createEnhancer();
		if (classLoader != null) {
			enhancer.setClassLoader(classLoader);
			if (classLoader instanceof SmartClassLoader &&
					((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
				enhancer.setUseCache(false);
			}
		}

		// 被代理类,代理类的父类。可以进行强转
		enhancer.setSuperclass(proxySuperClass);
		// 代理类额外要实现的接口。可以进行强转enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
		enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
		enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

		// 获取和被代理类所匹配的Advisor
		Callback[] callbacks = getCallbacks(rootClass);
		Class<?>[] types = new Class<?>[callbacks.length];
		for (int x = 0; x < types.length; x++) {
			types[x] = callbacks[x].getClass();
		}
		// fixedInterceptorMap only populated at this point, after getCallbacks call above
		enhancer.setCallbackFilter(new ProxyCallbackFilter(
				this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
		enhancer.setCallbackTypes(types);

		// Generate the proxy class and create a proxy instance.
		return createProxyClassAndInstance(enhancer, callbacks);
	}
	catch (CodeGenerationException | IllegalArgumentException ex) {
		throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
				": Common causes of this problem include using a final class or a non-visible class",
				ex);
	}
	catch (Throwable ex) {
		// TargetSource.getTarget() failed
		throw new AopConfigException("Unexpected AOP exception", ex);
	}
}

JDK动态代理的实现逻辑

/**
 * JDK动态代理实现逻辑
 */
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
	if (logger.isTraceEnabled()) {
		logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
	}
	// this实现了InvocationHandler
	return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}

/**
 * JDK动态代理的具体执行逻辑
 */
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 {
		// equals()方法直接执行。如果接口中没有定义equals()方法,那么则直接调用,不走代理
		if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
			// The target does not implement the equals(Object) method itself.
			return equals(args[0]);
		}
		// HashCode()方法直接执行。如果接口中没有定义HashCode()方法,那么则直接调用,不走代理
		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...
			// 也是直接调用Advised接口中的方法,不走代理逻辑
			// 其实就是利用代理对象获取ProxyFactory中的信息
			return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
		}

		Object retVal;

		// 如果ProxyFactory的exposeProxy为true,则将代理对象设置到currentProxy这个ThreadLocal中去。
		// 可以通过AopContext.currentProxy()来获取当前的代理对象
		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.
		// 调用getTarget得到被代理对象
		target = targetSource.getTarget();
		// 得到代理类
		Class<?> targetClass = (target != null ? target.getClass() : null);

		// Get the interception chain for this method.
		// 代理对象在执行某个方法时,根据方法筛选出匹配的Advisor,并适配成Interceptor
		// this.advised是ProxyFactory对象
		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.
		// chain是空的说明没有代理逻辑
		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.
			// 如果没有Advice,则直接调用对应方法
			Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
			retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
		}
		else {
			// 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);
		}
	}
}

/**
 * 无代理逻辑,直接执行被代理的方法
 */
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
		throws Throwable {

	// Use reflection to invoke the method.
	try {
		ReflectionUtils.makeAccessible(method);
		// 执行普通对象的方法,注意和@Configuration产生的代理对象的逻辑区别
		return method.invoke(target, args);
	}
	catch (InvocationTargetException ex) {
		// Invoked method threw a checked exception.
		// We must rethrow it. The client won't see the interceptor.
		throw ex.getTargetException();
	}
	catch (IllegalArgumentException ex) {
		throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
				method + "] on target [" + target + "]", ex);
	}
	catch (IllegalAccessException ex) {
		throw new AopInvocationException("Could not access method [" + method + "]", ex);
	}
}

/**
 * 代理对象在执行某个方法时,根据方法筛选出匹配的Advisor,并适配成Interceptor
 * method:被代理方法
 * targetClass:被代理类
 */
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
	// 代理对象在执行某个方法时,会根据当前ProxyFactory中所设置的Advisor根据当前Method再次进行过滤

	MethodCacheKey cacheKey = new MethodCacheKey(method);

	// 注意这个List,表示的就是Advice链。从缓冲中获取。
	List<Object> cached = this.methodCache.get(cacheKey);
	if (cached == null) {
		// 缓冲没有的时候,进行查找
		cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
				this, method, targetClass);
		this.methodCache.put(cacheKey, cached);
	}
	return cached;
}

/**
 * 缓冲中没有的情况下,构建Interceptors
 * config:ProxyFactory对象
 * method:被代理方法
 * targetClass:被代理类
 */
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();
	// 从ProxyFactory中拿到所设置的Advice(添加时被封装成了DefaultPointcutAdvisor)
	// 添加的时候会控制顺序。ProxyFactory.addAdvice的时候会添加。
	Advisor[] advisors = config.getAdvisors();
	List<Object> interceptorList = new ArrayList<>(advisors.length);
	Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
	Boolean hasIntroductions = null;

	// 遍历每一个Advisor
	for (Advisor advisor : advisors) {
		// PointcutAdvisor类型的处理
		if (advisor instanceof PointcutAdvisor) {
			// Add it conditionally.
			PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
			// 先匹配被代理的类是否符合getClassFilter的逻辑(一个Pointcut有俩个方法,一个是匹配类的,一个是匹配方法的)
			if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {

				// 再匹配方法是否符合getMethodMatcher的逻辑
				MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
				boolean match;
				if (mm instanceof IntroductionAwareMethodMatcher) {
					if (hasIntroductions == null) {
						hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
					}
					match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
				}
				else {
					match = mm.matches(method, actualClass);
				}

				// 方法匹配到了
				if (match) {
					// 如果匹配则将Advisor封装成为Interceptor,当前Advisor中的Advice可能即是MethodBeforeAdvice,也是ThrowsAdvice。
					MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
					// 方法匹配器的自定义方法isRuntime()返回true。
					if (mm.isRuntime()) {
						// Creating a new object instance in the getInterceptors() method
						// isn't a problem as we normally cache created chains.
						// isRuntime()返回true的时候,后面会进行参数的校验
						for (MethodInterceptor interceptor : interceptors) {
							interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
						}
					}
					else {
						interceptorList.addAll(Arrays.asList(interceptors));
					}
				}

				// 最终,interceptorList中存储的是当前正在执行的Method所匹配的MethodInterceptor,可能动态的,也可能是非动态的,
				// 找到Method所匹配的MethodInterceptor后,就会开始调用这些MethodInterceptor,如果是动态的,会额外进行方法参数的匹配
			}
		}
		// Introduction,指定接口的逻辑
		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 {
			// 将Advisor封装成为Interceptor
			Interceptor[] interceptors = registry.getInterceptors(advisor);
			interceptorList.addAll(Arrays.asList(interceptors));
		}
	}

	return interceptorList;
}

将Advisor封装成为Interceptor

/**
 * 将Advisor封装成为Interceptor
 */
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
	// 得到默认的三个MethodInterceptor的容器
	List<MethodInterceptor> interceptors = new ArrayList<>(3);
	// 根据传入的advisor得到advice
	Advice advice = advisor.getAdvice();
	// 属于MethodInterceptor,添加到interceptors中
	if (advice instanceof MethodInterceptor) {
		interceptors.add((MethodInterceptor) advice);
	}
	// 将Advice适配成MethodInterceptor
	for (AdvisorAdapter adapter : this.adapters) {
		// 判断传入的advice和这些适配器那个匹配
		if (adapter.supportsAdvice(advice)) {
			// 添加适配器的逻辑
			interceptors.add(adapter.getInterceptor(advisor));
		}
	}
	// 适配器为空,抛异常
	if (interceptors.isEmpty()) {
		throw new UnknownAdviceTypeException(advisor.getAdvice());
	}
	// 返回结果
	return interceptors.toArray(new MethodInterceptor[0]);
}

各种异处理器的执行逻辑

/**
 * 默认的3个适配器
 */
public DefaultAdvisorAdapterRegistry() {
	registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
	registerAdvisorAdapter(new AfterReturningAdviceAdapter());
	registerAdvisorAdapter(new ThrowsAdviceAdapter());
}

/**
 * 后置处理器执行逻辑,先执行其他逻辑,然后执行后置处理逻辑
 */
public Object invoke(MethodInvocation mi) throws Throwable {
	Object retVal = mi.proceed();
	this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
	return retVal;
}

/**
 * 前置处理器执行逻辑,先执行前置处理逻辑,然后执行其他逻辑
 */
public Object invoke(MethodInvocation mi) throws Throwable {
	this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
	return mi.proceed();
}

/**
 * 异常处理器执行逻辑:try catch 
 */
public Object invoke(MethodInvocation mi) throws Throwable {
	try {
		return mi.proceed();
	}
	catch (Throwable ex) {
		Method handlerMethod = getExceptionHandler(ex);
		if (handlerMethod != null) {
			invokeHandlerMethod(mi, ex, handlerMethod);
		}
		throw ex;
	}
}

链式执行的核心逻辑

public Object proceed() throws Throwable {

	// We start with an index of -1 and increment early.
	// currentInterceptorIndex初始值为-1,每调用一个interceptor就会加1
	// 当调用完了最后一个interceptor后就会执行被代理方法
	if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
		return invokeJoinpoint();
	}

	// currentInterceptorIndex初始值为-1
	Object interceptorOrInterceptionAdvice =
			this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);

	// 当前interceptor是InterceptorAndDynamicMethodMatcher,则先进行匹配,匹配成功后再调用该interceptor
	// 如果没有匹配则递归调用proceed()方法,调用下一个interceptor
	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.
			// 不匹配则执行下一个MethodInterceptor
			return proceed();
		}
	}
	else {

		// It's an interceptor, so we just invoke it: The pointcut will have
		// been evaluated statically before this object was constructed.
		// 直接调用MethodInterceptor,传入this,在内部会再次调用proceed()方法进行递归
		// 比如MethodBeforeAdviceInterceptor
		return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
	}
}

AOP是如何使用动态代理的

/**
 * 开启AOP的注解导入了AspectJAutoProxyRegistrar类
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	boolean proxyTargetClass() default false;

	boolean exposeProxy() default false;
}

/**
 * 被导入的类他是一个ImportBeanDefinitionRegistrar
 */
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		// 注册一个AnnotationAwareAspectJAutoProxyCreator类型的Bean,beanName为AUTO_PROXY_CREATOR_BEAN_NAME
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		// 修改AnnotationAwareAspectJAutoProxyCreator中对应的属性
		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			// 给proxyTargetClass默认值为true:默认使用cglib动态代理
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			// 给exposeProxy默认值为true:默认放入threadLocal中
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}
}

/**
 * 被导入的注册了一个AnnotationAwareAspectJAutoProxyCreator类型的Bean
 * 他是一个BeanPostProcessor,会在创建Bean的时候调用。
 */
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
}

/**
 * 在初始化的时候会执行postProcessAfterInitialization方法
 * 会调用到AbstractAutoProxyCreator的postProcessAfterInitialization
 */
@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;
}

/**
 * 初始化后会进入这个方法
 */
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	// beanName存在长度并且没有进行缓存(目前没找到他缓存放入的位置)
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}

	// advisedBeans表示已经判断过了的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)) {
		// 不需要进行AOP的标记放入缓存,下次进来第二个判断直接返回
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	// Create proxy if we have advice.
	// 判断当前bean是否存在匹配的advice,如果存在则要生成一个代理对象
	// 此处根据类以及类中的方法去匹配到Interceptor(也就是Advice),然后生成代理对象,代理对象在执行的时候,还会根据当前执行的方法去匹配
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	if (specificInterceptors != DO_NOT_PROXY) {
		// advisedBeans记录了某个Bean已经进行过AOP了
		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;
}

/**
 * 判断哪些类不需要进行AOP
 */
protected boolean isInfrastructureClass(Class<?> beanClass) {
	// AOP相关的类,不需要进行AOP
	boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
			Pointcut.class.isAssignableFrom(beanClass) ||
			Advisor.class.isAssignableFrom(beanClass) ||
			AopInfrastructureBean.class.isAssignableFrom(beanClass);
	if (retVal && logger.isTraceEnabled()) {
		logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
	}
	return retVal;
}

/**
 * 根据Bean信息找到Advices
 */
protected Object[] getAdvicesAndAdvisorsForBean(
		Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

	// 寻找匹配的Advisor
	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
	// 为空返回null
	if (advisors.isEmpty()) {
		return DO_NOT_PROXY;
	}
	return advisors.toArray();
}

/**
 * 根据Bean信息找到符合的条件的Advices
 */
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	// 找到所有的Advisor
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	// 进行筛选。Ian匹配类,后匹配方法
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);

	extendAdvisors(eligibleAdvisors);

	// 对Advisor进行排序,按Ordered接口、@Order注解进行排序
	if (!eligibleAdvisors.isEmpty()) {
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}

/**
 * 找到所有的Advisor
 */
protected List<Advisor> findCandidateAdvisors() {
	// Add all the Spring advisors found according to superclass rules.
	// 先找到所有Advisor类型的Bean对象。找到所有类型是Advisor的Bean。
	List<Advisor> advisors = super.findCandidateAdvisors();

	// Build Advisors for all AspectJ aspects in the bean factory.
	// 再从所有切面中解析得到Advisor对象。这里会解析@Aspect相关的注解的类。
	if (this.aspectJAdvisorsBuilder != null) {
		advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
	}
	return advisors;
}

/**
 * 创建代理对象
 */
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);

	if (proxyFactory.isProxyTargetClass()) {
		// Explicit handling of JDK proxy targets (for introduction advice scenarios)
		if (Proxy.isProxyClass(beanClass)) {
			// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
			for (Class<?> ifc : beanClass.getInterfaces()) {
				proxyFactory.addInterface(ifc);
			}
		}
	}
	else {
		// No proxyTargetClass flag enforced, let's apply our default checks...
		if (shouldProxyTargetClass(beanClass, beanName)) {
			proxyFactory.setProxyTargetClass(true);
		}
		else {
			evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}

	Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
	// 在这一步会去判断advisors中是否存在IntroductionAdvisor,如果存在则会把对应的interface添加到proxyFactory中去
	proxyFactory.addAdvisors(advisors);
	proxyFactory.setTargetSource(targetSource);
	customizeProxyFactory(proxyFactory);

	proxyFactory.setFrozen(this.freezeProxy);
	if (advisorsPreFiltered()) {
		proxyFactory.setPreFiltered(true);
	}

	// Use original ClassLoader if bean class not locally loaded in overriding class loader
	ClassLoader classLoader = getProxyClassLoader();
	if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
		classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
	}
	
	// AOP最核心的代码,创建代理对象!
	return proxyFactory.getProxy(classLoader);
}

@Aspect注解的相关解析

/*
 * 本方法会被多次调用,因为一个Bean在判断要不要进行AOP时,都会调用这个方法.
 */
public List<Advisor> buildAspectJAdvisors() {
	// aspectBeanNames是用来缓存BeanFactory中所存在的切面beanName的,第一次为null,后面就不为null了,不为null表示之前就已经找到过BeanFactory中的切面了
	List<String> aspectNames = this.aspectBeanNames;

	if (aspectNames == null) {
		synchronized (this) {
			aspectNames = this.aspectBeanNames;
			if (aspectNames == null) {
				List<Advisor> advisors = new ArrayList<>();
				aspectNames = new ArrayList<>();

				// 把所有beanNames拿出来遍历,判断某个bean的类型是否是Aspect
				String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
						this.beanFactory, Object.class, true, false);
				// 遍历所有的BeanName
				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.
					// 得到当前Bean的class对象
					Class<?> beanType = this.beanFactory.getType(beanName, false);
					if (beanType == null) {
						continue;
					}

					// 存在@Aspect注解的时候会进入当前判断
					if (this.advisorFactory.isAspect(beanType)) {
						// 标记为他有@Aspect注解
						aspectNames.add(beanName);
						// 切面的注解信息
						AspectMetadata amd = new AspectMetadata(beanType, beanName);

						// 如果@Aspect不是perthis、pertarget,那么一个切面只会生成一个对象(单例)
						// 并且会将该切面中所对应的Advisor对象进行缓存
						if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {

							MetadataAwareAspectInstanceFactory factory =
									new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
							// 利用BeanFactoryAspectInstanceFactory来解析Aspect类
							List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
							// 单例缓存Advisor,不是单例缓存Aspect工厂
							if (this.beanFactory.isSingleton(beanName)) {
								// 缓存切面所对应的所有Advisor对象
								this.advisorsCache.put(beanName, classAdvisors);
							}
							else {
								this.aspectFactoryCache.put(beanName, factory);
							}
							// 把advisor存入集合
							advisors.addAll(classAdvisors);
						}
						else {
							// Per target or per this.
							// 单例Bean,但是aspect不是单例的,抛异常
							if (this.beanFactory.isSingleton(beanName)) {
								throw new IllegalArgumentException("Bean with name '" + beanName +
										"' is a singleton, but aspect instantiation model is not singleton");
							}
							MetadataAwareAspectInstanceFactory factory =
									new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
							this.aspectFactoryCache.put(beanName, factory);
							// 利用PrototypeAspectInstanceFactory来解析Aspect类
							// PrototypeAspectInstanceFactory的父类为BeanFactoryAspectInstanceFactory
							// 这两个Factory的区别在于PrototypeAspectInstanceFactory的构造方法中会判断切面Bean是不是原型,除此之外没有其他区别
							// 所以主要就是BeanFactoryAspectInstanceFactory来负责生成切面实例对象
							advisors.addAll(this.advisorFactory.getAdvisors(factory));
						}
					}
				}
				this.aspectBeanNames = aspectNames;
				// 循环完成,返回advisor
				return advisors;
			}
		}
	}

	// 空长度的aspectNames,返回空长度的数组
	if (aspectNames.isEmpty()) {
		return Collections.emptyList();
	}

	// 如果切面已经找到过了,那么则遍历每个切面是否缓存了对应的Advisor,如果没有缓存则进行解析得到Advisor
	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;
}

/*
 * 拿到所有的Advisor方法,没有加@Pointcut的方法
 */
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
	List<Method> methods = new ArrayList<>();
	// 拿到切面类中所有没有加@Pointcut的方法
	ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
	// 对方法进行排序,按注解和方法名字进行排序
	if (methods.size() > 1) {
		methods.sort(adviceMethodComparator);
	}
	return methods;
}

/*
 * 切面的排序逻辑
 */
static {
	// 简单理解先后顺序为:@Around, @Before, @After, @AfterReturning, @AfterThrowing
	Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
			new InstanceComparator<>(
					Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
			(Converter<Method, Annotation>) method -> {
				AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
				return (ann != null ? ann.getAnnotation() : null);
			});

	// 存在多个相同的,比如多个@Before,会按照方法的名字进行排序(字母排序)。
	Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
	adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
}

/*
 * 得到所有的Advisor
 */
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
	// 得到aspect的类信息
	Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
	// 得到aspect的名称
	String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
	validate(aspectClass);

	// 保证切面Bean对象只会实例化一次
	// 一定要注意,这里是直接new出来一个LazySingletonAspectInstanceFactoryDecorator
	// 也就是BService这个Bean在执行Bean生命周期过程中,会需要判断要不要进行AOP,就会找到切面,
	// 发现切面如果是pertarget或perthis,那么就会进入到这个方法,就会new一个LazySingletonAspectInstanceFactoryDecorator
	// 对于AService也是一样的,在它的Bean的生命周期过程中,也会进入到这个方法,也会new一个LazySingletonAspectInstanceFactoryDecorator
	MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
			new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

	List<Advisor> advisors = new ArrayList<>();
	// 获取切面类中没有加@Pointcut的方法,进行遍历生成Advisor
	for (Method method : getAdvisorMethods(aspectClass)) {
		
		// 得到(解析)为Advisor
		Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
		// 解析出来存起来
		if (advisor != null) {
			advisors.add(advisor);
		}
	}

	// @Aspect("pertarget(this(com.zhangwei.service.UserService))")
	// @Aspect("perthis(this(com.zhangwei.service.UserService))")
	// 如果是pertarget或perthis,则会多生成一个Advisor并放在最前面
	// 在一个代理对象调用方法的时候,就会执行该Advisor,并且会利用lazySingletonAspectInstanceFactory来生成一个切面Bean
	if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
		Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
		advisors.add(0, instantiationAdvisor);
	}

	// Find introduction fields.
	// 找到哪些字段上加了@DeclareParents注解,把这些字段以及对于的注解解析封装为Advisor,生成代理对象时会把对于的接口添加到ProxyFactory中
	for (Field field : aspectClass.getDeclaredFields()) {
		Advisor advisor = getDeclareParentsAdvisor(field);
		if (advisor != null) {
			advisors.add(advisor);
		}
	}

	return advisors;
}

/*
 * 解析成Advisor
 */
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
		int declarationOrderInAspect, String aspectName) {

	validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

	// 拿到当前方法所对应的Pointcut对象,但是注意:如果当前方法上是这么写的@After("pointcut()"),那么此时得到的Pointcut并没有去解析pointcut()得到对应的表达式
	AspectJExpressionPointcut expressionPointcut = getPointcut(
			candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
	// 没有pointcut直接返回空!
	if (expressionPointcut == null) {
		return null;
	}

	// expressionPointcut是pointcut
	// candidateAdviceMethod承载了advice
	return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
			this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

/*
 * 解析成Pointcut
 */
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
	// 拿到切面中某个方法上的注解信息
	AspectJAnnotation<?> aspectJAnnotation =
			AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
	if (aspectJAnnotation == null) {
		return null;
	}

	// 得到一个AspectJExpressionPointcut对象
	AspectJExpressionPointcut ajexp =
			new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
	ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
	if (this.beanFactory != null) {
		ajexp.setBeanFactory(this.beanFactory);
	}
	return ajexp;
}

常用的@Before、@Before....解析流程

/**
 * 源码入口:org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl.getAdvice()
 * 当前核心逻辑入口:org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvice(Method, AspectJExpressionPointcut, MetadataAwareAspectInstanceFactory, int, String)
 */
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
		MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

	// 得到@Aspect注解的信息
	Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
	validate(candidateAspectClass);

	// 拿到当前candidateAdviceMethod方法上的注解信息
	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:
			// @Around
			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;
}

结束语

  • 获取更多本文的前置知识文章,以及新的有价值的文章,让我们一起成为架构师!
  • 关注公众号,可以让你对MySQL、并发编程、spring源码有深入的了解!
  • 关注公众号,后续持续高效的学习JVM!
  • 这个公众号,无广告!!!每日更新!!!
    作者公众号.jpg

推荐阅读