【Spring 源码解析】从AbstractAutowireCapableBean的applyBeanPostProcessorsAfterInitialization()方法看AOP原理

本文详细解析了Spring框架中AOP(面向切面编程)的实现原理,包括动态代理的生成方式、代理对象的创建过程及如何触发AOP通知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【Bean的生命周期】中得知,在实例化Bean完成之后会调用init方法,然后再调用AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization()方法生成一个代理对象,其实不管是我们getBean()获取到的对象还是AOP中真正使用的对象都是这个代理对象wrappedBean

if (mbd == null || !mbd.isSynthetic()) {
	wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;

所以我们要从这个方法进去看AOP的整体流程:

	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

可以看到这里就是调用每个BeanPostProcessor的postProcessAfterInitialization()方法生成一个对象,如果其中遇到一个BeanPostProcessor生成一个空对象,就直接返回之前生成的最后一个非空代理对象。那么AOP到底是通过哪个具体的BeanPostProcessor来生成对象的呢?

一、AOP中的动态代理

首先我们如果是通过@EnableAspectJAutoProxy注解的方式开启注解功能的话,会导入一个AspectJAutoProxyRegistrar类,这个类实现了ImportBeanDefinitionRegistrar接口:

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
	/**
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 * {@code @Configuration} class.
	 */
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		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);
			}
		}
	}

}

registerBeanDefinitions()方法中通过AopConfigUtils注册了AnnotationAwareAspectJAutoProxyCreator这个Bean:

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

AnnotationAwareAspectJAutoProxyCreator注册成功。

AnnotationAwareAspectJAutoProxyCreator的继承关系图:
aaaapc
很显然,它就是一个BeanPostProcessor,但是它里面并没有实现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;
	}

内部就是通过wrapIfNecessary(bean, beanName, cacheKey)来生成的代理对象。继续看:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	//是否需要代理这个bean
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
	//是否是Advice,PointCut等这些基础类,或者是否需要调过代理
	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);
	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;
}

注意createProxy()方法里面最终调用了DefaultAopProxyFactory.createAopProxy()方法创建一个代理对象:

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	if (!IN_NATIVE_IMAGE &&
			(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.");
		}
		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
			return new JdkDynamicAopProxy(config);
		}
		return new ObjenesisCglibAopProxy(config);
	}
	else {
		return new JdkDynamicAopProxy(config);
	}
}

可以看到实际上是JdkDynamicAopProxyObjenesisCglibAopProxy两种动态代理。如果原先的类实现了接口或者就是Proxy类,那么使用JDK动态代理,否则使用Cglib。

二、Spring 生成代理对象

刚刚只是获取了代理AopProxy,并未生成真正的代理对象,需要调用两个代理的getProxy()方法。我们这里主要分析一下JDK动态代理生成代理对象以及执行代理方法的过程:

1. 生成代理对象

先来看看JdkDynamicAopProxy的getProxy()方法:

@Override
public Object getProxy() {
	return getProxy(ClassUtils.getDefaultClassLoader());
}

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
	return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}

和我们平常使用的一样,就是通过Proxy类的newProxyInstance()方法创建了一个代理对象。同时这个proxiedInterfaces变量表示需要增强的方法,也就是带有通知的连接点,已经在构造函数中通过AopProxyUtils.completeProxiedInterfaces(this.advised, true)获取。

2. 执行代理方法

InvocationHandler是JDK动态代理的核心,生成的代理对象的方法都会委派到invoke()方法中执行,对于AOP来说,这就是一个织入的过程。而JdkDynamicAopProxy本身已经实现了InvocationHandler这个接口,所以看一下它的invoke()方法:

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

		Object retVal;

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

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

		// Get the interception chain for this method.
		//获取这个方法相关的拦截器
		List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

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

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

主要思路就是有拦截器则应用拦截器并执行连接点,如果没有拦截器直接反射执行方法。

3. 触发AOP的通知

上面已经说了,在InvokeHandler中通过invoke()调用代理方法的过程中如果有拦截器,会应用拦截器,也就是递归调用拦截器内部的proceed()方法。因此,AOP的通知其实就是通过拦截器来实现的。

(1)拦截器的生成

拦截器是通过this.advised.getInterceptorsAndDynamicInterceptionAdvice()方法获取的,而这个方法其实最终执行的是DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()方法:

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

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

	for (Advisor advisor : advisors) {
		if (advisor instanceof PointcutAdvisor) {
			// Add it conditionally.
			PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
			if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
				MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
				boolean match;
				if (mm instanceof IntroductionAwareMethodMatcher) {
					if (hasIntroductions == null) {
						hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
					}
					match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
				}
				else {
					match = mm.matches(method, actualClass);
				}
				if (match) {
					MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
					if (mm.isRuntime()) {
						// Creating a new object instance in the getInterceptors() method
						// isn't a problem as we normally cache created chains.
						for (MethodInterceptor interceptor : interceptors) {
							interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
						}
					}
					else {
						interceptorList.addAll(Arrays.asList(interceptors));
					}
				}
			}
		}
		else if (advisor instanceof IntroductionAdvisor) {
			IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
			if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}
		else {
			Interceptor[] interceptors = registry.getInterceptors(advisor);
			interceptorList.addAll(Arrays.asList(interceptors));
		}
	}

	return interceptorList;
}

AbstractAutoProxyCreator.createProxy()方法创建代理对象时已经提前创建好Advisor对象了:

Advisor[] advisors = buildAdvisors(beanName, specificInterceptors)

并且在DefaultAdvisorAdapterRegistry类中注册了各种AdviceAdapter:

public DefaultAdvisorAdapterRegistry() {
	registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
	registerAdvisorAdapter(new AfterReturningAdviceAdapter());
	registerAdvisorAdapter(new ThrowsAdviceAdapter());
}

而在getInterceptorsAndDynamicInterceptionAdvice()方法中调用getInterceptors()方法,并通过这些Adapter的getInterceptor()方法,将Advice对象转化为MethodInterceptor对象

@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
	List<MethodInterceptor> interceptors = new ArrayList<>(3);
	Advice advice = advisor.getAdvice();
	if (advice instanceof MethodInterceptor) {
		interceptors.add((MethodInterceptor) advice);
	}
	for (AdvisorAdapter adapter : this.adapters) {
		if (adapter.supportsAdvice(advice)) {
			interceptors.add(adapter.getInterceptor(advisor));
		}
	}
	if (interceptors.isEmpty()) {
		throw new UnknownAdviceTypeException(advisor.getAdvice());
	}
	return interceptors.toArray(new MethodInterceptor[0]);
}

这样就生成了通知对应的拦截器对象了。

(2)拦截器的执行

就两行代码:

// 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();

首先就是先实例化一个ReflectiveMethodInvocation对象,重点看一下它的proceed()方法:

@Override
@Nullable
public Object proceed() throws Throwable {
	// We start with an index of -1 and increment early.
	if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
		return invokeJoinpoint();
	}
 
	Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
	if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
		// Evaluate dynamic method matcher here: static part will already have
		// been evaluated and found to match.
		InterceptorAndDynamicMethodMatcher dm =
				(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
		Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
		if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
			return dm.interceptor.invoke(this);
		}
		else {
			// Dynamic matching failed.
			// Skip this interceptor and invoke the next in the chain.
			return proceed();
		}
	}
	else {
		// It's an interceptor, so we just invoke it: The pointcut will have
		// been evaluated statically before this object was constructed.
		return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
	}
}

首先这段代码保证拦截链的最后一个拦截器执行完成返回的结果等效于拦截链的proceed()方法,不至于最后返回一个空:

	if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
		return invokeJoinpoint();
	}

然后就是依次获取一个拦截器,如果该拦截器的方法和当前方法一致,表示属于当前拦截链,则执行方法:

if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
	return dm.interceptor.invoke(this);
}

否则,调用proceed()方法执行下一个拦截链。


THE END.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值