Spring 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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
isInterface和Proxy.isProxyClass
可以看到,对于是否使用JDK动态代理其实做了两个判断
isInterface
这个比较明确,就是判定代理的是否是接口,不做太多展开。
Proxy.isProxyClass
这个又是什么呢?从名称上大致可以看出是用来判定是否代理的代理类。打开相关源码看下
/**
* Returns true if and only if the specified class was dynamically
* generated to be a proxy class using the {@code getProxyClass}
* method or the {@code newProxyInstance} method.
*
* <p>The reliability of this method is important for the ability
* to use it to make security decisions, so its implementation should
* not just test if the class in question extends {@code Proxy}.
*
* @param cl the class to test
* @return {@code true} if the class is a proxy class and
* {@code false} otherwise
* @throws NullPointerException if {@code cl} is {@code null}
*/
public static boolean isProxyClass(Class<?> cl) {
return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
}
可以看到,此处做了两个判断:
- 是否是Proxy的子类
- 是否存在于缓存中
这两个判断其实判断只做了一件事:确定当前的class是否是JDK生成的动态代理类。因为JDK生成动态代理的机制就是继承Proxy类并且放置到缓存中。
注意: 此处的Proxy是jdk reflect包中的类。为何这么判断是否是代理类可参见有点深度的聊聊JDK动态代理。
总结
综上所述,两种情况可以使用JDK动态代理:
- 代理的是接口
- 代理的是使用了JDK动态代理的代理类。