主要代码:DefaultAopProxyFactory#createAopProxy()
在之前讲到 DefaultAopProxyFactory 是默认的创建代理的工厂类,会根据传入的被代理类来选择不同的创建策略。
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
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 类型的 Bean 要创建 JDK 动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 其他情况会创建 CGLib 动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
// 使用 JDK 动态代理
return new JdkDynamicAopProxy(config);
}
}
JDK 动态代理
主要代码:JdkDynamicAopProxy#getProxy()
在这个过程中,主要是通过 AopProxyUtils.completeProxiedInterfaces() 进行被代理接口的筛选,在 Java 中,我们都知道一个类只能继承一个父类,但是可以实现多个接口,所以要找到被代理的接口需要做一堆工作。
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// 获取需要代理的接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
// 找 EqualsAndHashCode 方法
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// JDK 动态代理的获取目标类的主要方法
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
主要代码:JdkDynamicAopProxy#invoke()
在方法中,会发现 this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 这么一行方法,这边主要是使用了责任链模式对 Advisors 进行封装成链,以便后续继续使用。
@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 {
// 目标未实现 equals 方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
// 目标未实现 hashCode 方法
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
// 直接反射调用
else if (!this.advised.opaque && method.getDeclaringClass