回顾
之前我们已经详细说明了Bean是如何被代理的,最终Bean会被解析成JdkDynamicAopProxy或者ObjenesisCglibAopProxy对象了,对应JDK代理和Cglib代理,下面就来仔细看看这两个对象吧
还是回到之前DefaultAopProxyFactory的createAopProxy

这里的config已经有了之前解析出来的增强器和拦截器了(一个总的数组集合)、还有一些Bean的信息
JdkDynamicAopProxy
先进来看看这个类

可以看到这个类实现了InvocationHandler,这下估计都懂怎么回事了吧。。。
先看一下它的构建方法
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
//判断增强器和拦截器的数量
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
//如果为0就抛出异常
throw new AopConfigException("No advisors and no TargetSource specified");
}
//注入配置
this.advised = config;
//看不懂。。。
this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
//判断有没有定义的equals方法和hashCode方法
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
}
可以看到,构造方法只是注入了一下属性,并且判断增强器和拦截器的数量而已,比较重要的是查找有有没有定义的equals方法和hashCode方法
JdkDynamicAopProxy就是一个JDK的proxy代理类,所以我们去关注它的invoke方法
源码如下,很长,一看就很复杂
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
//获取被增强的对象的Class
//这里比较特殊,之前的动态代理,我们都是直接new一个进来的
//那么此时被代理的对象都还没有被IOC容器创建完,要怎么获取实例呢?
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.
//如果没有重写equals方法,那就使用默认的equals方法
return equals(args[0]);
}
//对hashCode方法进行同样处理
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
//如果当前之心的方法的类型是DecoraingProxy.class
//执行下面的逻辑
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
//如果执行的方法是来自于接口的,并且方法属于的类还是一个Advised.class
//证明了这是代理对象的代理对象(即被代理对象是一个代理对象,还实现了接口)
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
//执行invokeJoinpointUsingReflection
return AopUtils.invokeJoinpointUsingReflection(this.advised, method

本文深入探讨了Spring AOP中的JdkDynamicAopProxy工作原理,包括如何解决内部调用无法被代理拦截的问题,以及在创建Bean时如何通过三级缓存解决循环依赖。
最低0.47元/天 解锁文章
1497

被折叠的 条评论
为什么被折叠?



