spring boot源码分析(五):spring aop(二)

本文深入探讨Spring框架中的AOP实现原理,详细分析ProxyFactory类的构造过程及如何生成代理对象,包括JDK动态代理与CGLIB代理的选择机制。同时,介绍了Advisor与Advice的转换流程,以及MethodInterceptor的创建与执行机制。

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

ProxyFactory源码

实例

public class Aop {
    public static void main(String[] args) {
        IUser user = new User();
        ProxyFactory factory = new ProxyFactory();
        factory.setTarget(user);
        factory.setInterfaces(IUser.class);
        factory.addAdvice(new LogAdvice());
        factory.addAdvice(new Log2Advice());
        factory.addAdvice(new AfterReturningAdviceInterceptor(new AfterReturningAdvice() {
            @Override
            public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
                System.out.println("clearn-----------------");
            }
        }));
        IUser proxyUser = (IUser) factory.getProxy();
        proxyUser.echo();
    }
}
public interface IUser {
    public void echo();
}

public class LogAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("log----------");
    }
}
public class Log2Advice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("log2----------------");
    }
}
public class User implements IUser{
    public void echo(){
        System.out.println("lixinlei");
    }
}

源码分析

首先看一下ProxyFactory的继承层次
在这里插入图片描述
Advised主要提供了Advisor的管理类
ProxyConfig则提供了生成代理对象的配置管理
ProxyFactory因此可以添加Advisor和管理代理对象的配置

Advised

在这里插入图片描述

ProxyConfig

ProxyConfig主要用来提供生成代理对象相关的属性

public class ProxyConfig implements Serializable {

	/** use serialVersionUID from Spring 1.2 for interoperability */
	private static final long serialVersionUID = -8409359707199703185L;

	// 使用使用cglib来生成代理
	private boolean proxyTargetClass = false;
	
	// 判断是否需要进行优化,如果需要进行优化,当代理对象创建之后将不能添加advisor另外会使用cglib来生成代理对象
	private boolean optimize = false;
	
	// 是否可以强制转换成Advised
	boolean opaque = false;

	// 当生成代理对象之后,将代理对象放入到线程本地变量中,供被代理对象访问
	boolean exposeProxy = false;

	// 当设置frozen之后,无法对对配置进行修改,比如无法添加Advisor和移除Advisor
	private boolean frozen = false;
}

ProxyFactory

构造方法
public ProxyFactory(Object target) {
	// 使用目标对象,创建一个SingletonTargetSource
	setTarget(target);
	// 获取目标对象实现的所有接口,设置为代理对象需要实现的接口
	setInterfaces(ClassUtils.getAllInterfaces(target));
}

public ProxyFactory(Class<?>... proxyInterfaces) {
	setInterfaces(proxyInterfaces);
}

public ProxyFactory(Class<?> proxyInterface, Interceptor interceptor) {
	addInterface(proxyInterface);
	// 设置增强逻辑
	addAdvice(interceptor);
}

public ProxyFactory(Class<?> proxyInterface, TargetSource targetSource) {
	addInterface(proxyInterface);
	setTargetSource(targetSource);
}
getProxy
public Object getProxy() {
	return createAopProxy().getProxy();
}
protected final synchronized AopProxy createAopProxy() {
	if (!this.active) {
		activate();
	}
	// 获取配置使用的AopProxyFactory,如果没有设置,默认情况下是DefaultAopProxyFactory
	return getAopProxyFactory().createAopProxy(this);
}

接着看下DefaultAopProxyFactory的createAopProxy

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	// 根据配置来决定使用哪种代理生成方式
	// 一下三种情况会尝试使用cglib方式来生成代理
	// config设置optimize为true
	// config设置proxyTargetClass为true
	// config中没有设置需要代理的接口
	if (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.");
		}
		// 如果目标类本身是一个接口或者该类实现了Proxy
		// 使用jdk原生的代理方式
		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
			return new JdkDynamicAopProxy(config);
		}
		// 使用cglib来生成代理
		return new ObjenesisCglibAopProxy(config);
	}
	else {
		return new JdkDynamicAopProxy(config);
	}
}

JdkDynamicAopProxy

JdkDynamicAopProxy使用的是jdk原生提供的代理生成能力,其实现了InvocationHandler接口
在这里插入图片描述

getProxy
public Object getProxy(ClassLoader classLoader) {
	if (logger.isDebugEnabled()) {
		logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
	}
	Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
	findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
	return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
completeProxiedInterfaces

用来生成全部需要进行代理的接口集合

static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
	// 从配置中获取需要代理的接口
	Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
	if (specifiedInterfaces.length == 0) {
		// No user-specified interfaces: check whether target class is an interface.
		// 没有手动指定需要代理的接口
		Class<?> targetClass = advised.getTargetClass();
		if (targetClass != null) {
			// 目标类本身是一个接口
			// 将该接口设置为需要代理的接口
			if (targetClass.isInterface()) {
				advised.setInterfaces(targetClass);
			}
			else if (Proxy.isProxyClass(targetClass)) {
				// 目标类实现了Proxy接口,将当前类实现的所有接口作为需要代理的接口
				advised.setInterfaces(targetClass.getInterfaces());
			}
			specifiedInterfaces = advised.getProxiedInterfaces();
		}
	}
	// 判断SpringProxy是否需要代理
	boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
	// 如果配置中opaque设置为false从而需要将代理强转为Advised,并且Advise接口本身不在需要代理的接口集合中
	boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
	// 判断是否需要代理DecoratingProxy接口
	boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
	int nonUserIfcCount = 0;
	if (addSpringProxy) {
		nonUserIfcCount++;
	}
	if (addAdvised) {
		nonUserIfcCount++;
	}
	if (addDecoratingProxy) {
		nonUserIfcCount++;
	}
	// 重新生成需要代理的接口数组
	Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
	System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
	int index = specifiedInterfaces.length;
	if (addSpringProxy) {
		proxiedInterfaces[index] = SpringProxy.class;
		index++;
	}
	if (addAdvised) {
		proxiedInterfaces[index] = Advised.class;
		index++;
	}
	if (addDecoratingProxy) {
		proxiedInterfaces[index] = DecoratingProxy.class;
	}
	return proxiedInterfaces;
}
findDefinedEqualsAndHashCodeMethods
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
	// 遍历需要代理的接口
	for (Class<?> proxiedInterface : proxiedInterfaces) {
		// 遍历当前接口声明的方法
		Method[] methods = proxiedInterface.getDeclaredMethods();
		for (Method method : methods) {
			// 判断是否是equals方法
			if (AopUtils.isEqualsMethod(method)) {
				this.equalsDefined = true;
			}
			// 判断是否是hashCode方法
			if (AopUtils.isHashCodeMethod(method)) {
				this.hashCodeDefined = true;
			}
			if (this.equalsDefined && this.hashCodeDefined) {
				return;
			}
		}
	}
}
handle

getProxy方法中,在创建代理对象的时候,会将JdkDynamicAopProxy本身作为增强,因此看下invoke方法来看下增强逻辑

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	MethodInvocation invocation;
	Object oldProxy = null;
	boolean setProxyContext = false;

	TargetSource targetSource = this.advised.targetSource;
	Class<?> targetClass = null;
	Object target = null;

	try {
		// 当前调用的方法是equlas并且目标类本身没有实现equals方法
		if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
			// The target does not implement the equals(Object) method itself.
			// 调用JdkDynamicAopProxy的equals
			return equals(args[0]);
		}
		// 当前调用的方法是hashCode并且目标类本身没有实现hashCode方法
		else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
			// The target does not implement the hashCode() method itself.
			// 调用JdkDynamicAopProxy的hashCode
			return hashCode();
		}
		// 调用的是DecoratingProxy定义的方法
		else if (method.getDeclaringClass() == DecoratingProxy.class) {
			// There is only getDecoratedClass() declared -> dispatch to proxy config.
			return AopProxyUtils.ultimateTargetClass(this.advised);
		}
		// 当前调用的是Advised接口的方法,并且配置设置为可以强转为Advised
		else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
				method.getDeclaringClass().isAssignableFrom(Advised.class)) {
			// Service invocations on ProxyConfig with the proxy config...
			// 将请求代理到配置advised上
			return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
		}

		Object retVal;

		// 配置中设置需要暴露代理对象,将代理对象设置到线程本地变量中
		if (this.advised.exposeProxy) {
			// Make invocation available if necessary.
			oldProxy = AopContext.setCurrentProxy(proxy);
			setProxyContext = true;
		}

		// May be null. Get as late as possible to minimize the time we "own" the target,
		// in case it comes from a pool.
		// 记录目标类的类型
		target = targetSource.getTarget();
		if (target != null) {
			targetClass = target.getClass();
		}

		// Get the interception chain for this method.
		// 创建interception链
		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...
			// 需要进行增强,创建ReflectiveMethodInvocation,并执行
			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);
		}
	}
}
getInterceptorsAndDynamicInterceptionAdvice
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
	// 缓存interception chain
	MethodCacheKey cacheKey = new MethodCacheKey(method);
	List<Object> cached = this.methodCache.get(cacheKey);
	if (cached == null) {
		cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
				this, method, targetClass);
		this.methodCache.put(cacheKey, cached);
	}
	return cached;
}
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, Class<?> targetClass) {

	// This is somewhat tricky... We have to process introductions first,
	// but we need to preserve order in the ultimate list.
	// 获取配置中的advisor
	List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
	Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
	// 判断是否需要做introduction
	boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
	AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
	
	for (Advisor advisor : config.getAdvisors()) {
		if (advisor instanceof PointcutAdvisor) {
			// Add it conditionally.
			PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
			// config.isPreFiltered返回true,代表config中的所有advisor都是适用于当前目标对象的
			// 判断当前advisor需要对当前目标对象进行增强
			if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
				// 方法匹配
				MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
				if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
					// 将当前advisor包含的advice转换成MethodInterceptor
					MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
					// 如果MethodMatcher的runtime是true,那么代表在进行是否需要增强的时候,需要考虑参数
					if (mm.isRuntime()) {
						// Creating a new object instance in the getInterceptors() method
						// isn't a problem as we normally cache created chains.
						// 单独将需要考虑参数的MethodMatcher下面的advice转换成InterceptorAndDynamicMethodMatcher
						for (MethodInterceptor interceptor : interceptors) {
							interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
						}
					}
					else {
						// 将advice转换成的interceptor加入到最终结果中
						interceptorList.addAll(Arrays.asList(interceptors));
					}
				}
			}
		}
		// 相同的方法处理IntroductionAdvisor
		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;
}
getInterceptors

下面看下DefaultAdvisorAdapterRegistry中的getInterceptors是如何将各种类型的advisor转换成MethodInterceptor的

public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
	List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
	Advice advice = advisor.getAdvice();
	// 如果advice本身就是MethodInterceptor,不做处理
	if (advice instanceof MethodInterceptor) {
		interceptors.add((MethodInterceptor) advice);
	}
	// 使用AdvisorAdapter对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[interceptors.size()]);
}

DefaultAdvisorAdapterRegistry构造的时候会添加如下三个adapter,分别将MethodBeforeAdvice,AfterReturningAdvice和ThrowsAdvice转换成MethodInterceptor

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

代码比较简单,直接看代码

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof MethodBeforeAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
		return new MethodBeforeAdviceInterceptor(advice);
	}

}
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {

	private final MethodBeforeAdvice advice;


	/**
	 * Create a new MethodBeforeAdviceInterceptor for the given advice.
	 * @param advice the MethodBeforeAdvice to wrap
	 */
	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}


	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		// 在执行target真实逻辑之前,执行advice的before逻辑
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
		return mi.proceed();
	}

}
AfterReturningAdviceAdapter
class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof AfterReturningAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
		return new AfterReturningAdviceInterceptor(advice);
	}

}
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

	private final AfterReturningAdvice advice;


	/**
	 * Create a new AfterReturningAdviceInterceptor for the given advice.
	 * @param advice the AfterReturningAdvice to wrap
	 */
	public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}


	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		Object retVal = mi.proceed();
		// 在target执行完真实逻辑之后,执行afterReturning
		this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
		return retVal;
	}

}
ThrowsAdviceAdapter
class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof ThrowsAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		return new ThrowsAdviceInterceptor(advisor.getAdvice());
	}

}
public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
	// 省略
	@Override
	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;
		}
	}
}
proceed

通过递归的方式来执行所有增强,一层包着一层,最里面是目标对象的执行逻辑

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);
	// 之前讲过,当MethodMatcher的runtime返回true,代表需要考虑参数来决定是否进行增强时,会将Advice转换成InterceptorAndDynamicMethodMatcher
	if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
		// Evaluate dynamic method matcher here: static part will already have
		// been evaluated and found to match.
		InterceptorAndDynamicMethodMatcher dm =
				(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
		// 判断参数是否匹配
		if (dm.methodMatcher.matches(this.method, this.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 {
		// 其他类型的interceptor
		// 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);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值