【源码】Spring AOP 11 AopProxyFactory AopProxy
前言
这章节我们介绍代理创建器工厂 AopProxyFactory 和具体的代理创建器 AopProxy,它们真正负责代理对象的创建
AopProxyFactory
public interface AopProxyFactory {
AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
}
- 代理创建器工厂接口
createAopProxy
方法基于Advised
代理信息创建对应的代理创建器AopProxy
DefaultAopProxyFactory
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
// ...
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
/**
* 如果是指定了 optimize 或 proxyTargetClass 或 没指定代理接口
* 则会尝试使用 CGLIB 代理,否则就 JDK 代理
*/
if (!NativeDetector.inNativeImage() &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("...");
}
// 如果当前指定的类是个接口或者是 Proxy 类,那继续 JDK 代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 否则就 CGLIB 了
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
// ...
}
- 众所周知,动态代理方式有两种,基于
JDK
的动态代理和基于CGLIB
的动态代理 - 此处就是基于代理配置选择创建对应的代理创建器,
JdkDynamicAopProxy
和ObjenesisCglibAopProxy
AopProxy
public interface AopProxy {
// 获取代理对象
Object getProxy();
// 指定类加载器
Object getProxy(@Nullable ClassLoader classLoader);
}
代理创建器,用于真正创建代理对象
JdkDynamicAopProxy
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
/** getProxy **/
@Override
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
// ...
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
/** invoke from InvocationHandler **/
@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 {
// ...
Object retVal;
// 暴露为当前线程可见(ThreadLocal)
// 这里是暴露在 InvocationHandler 的调用线程中而不是创建代理的线程哦
// 因此在通知方法中我们可以获取到 proxy 对象: AopContext#getCurrentProxy
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 这个方法是 AdvisedSupport 提供的,委托给 DefaultAdvisorChainFactory 实现的
// 获取指定类方法上的所有 Interceptor
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 如果没有拦截链
if (chain.isEmpty()) {
// 参数处理并直接调原始方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
// 如果有就把当前方法和 Interceptors Chain 封装成 ReflectiveMethodInvocation
// 这里就会产生 MethodInvocation#proeed 和 MehthodInterceptor#invoke 的递归
else {
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
// ... 结果的一些处理
return retVal;
}
// ...
}
}
JDK动态代理
,即我们熟悉的Proxy.newProxyInstance(classLoader, proxiedInterfaces, this)
- 可以看到传入的
InvocationHandler
是this
,这意味着代理的实际行为取决于invoke
方法,invoke
方法大体概括:- 在进行一些必要的处理后,首先会把当前代理对象暴露到
ThreadLocal
中,我们可以使用AopContext#getCurrentProxy
直接获取哦 - 会基于父类方法
AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice
方法获取当前方法的拦截链,本质就是Advisor
s 的匹配与适配 - 对于拦截链为空的方法,直接执行即可,否则构造对应的
ReflectiveMethodInvocation
,之前了解过,ReflectiveMethodInvocation
就是对整个代理方法的执行,其proceed
方法会跟MethodInterceptor#invoke
形成递归,最终执行使用拦截器 - 处理结果并返回
- 在进行一些必要的处理后,首先会把当前代理对象暴露到
CglibAopProxy
- 跟
JDK动态代理
相对的,基于CGLIB
的代理 - 其底层依赖的是
Enhancer
相关API
- 这里使用的是它的子类
ObjenesisCglibAopProxy
- 具体源码就不深入了解了
总结
至此,我们了解了
AOP
相关的核心组件和对应的API
体系,比如Advice
Joinpoint
Pointut
Advisor
等Advised
下我们了解了如何创建最终的代理对象,以及它的代理原理
接下来,就可以了解下,Spring AOP
是在什么阶段如何针对 bean 组件创建对应的代理对象的
序列图
get the proxy
上一篇:【源码】Spring AOP 10 ProxyFactoryBean ProxyFactory AspectJProxyFactory
参考
【小家Spring】详解Spring AOP的底层代理JdkDynamicAopProxy和ObjenesisCglibAopProxy的源码分析(介绍CGLIB使用中的坑)