ProxyFactory是怎么区分要使用JDK动态代理生成代理对象,还是要使用CGLIB生成代理对象?
先看下ProxyFactory的createAopProxy()的这个方法源码
if (!NativeDetector.inNativeImage() &&
(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);
}
NativeDetector.inNativeImage():判断是不是在GraalVM虚拟机上运行
config.isOptimize():为true时,Spring认为cglib比jdk动态代理要快
config.isProxyTargetClass():判断被代理的是不是类
hasNoUserSuppliedProxyInterfaces(config):判断被代理对象有没有实现接口,或者只实现了SpringProxy这个接口
targetClass.isInterface():如果被代理类是接口,则进行JDK动态代理,(这种情况很少出现)
Proxy.isProxyClass(targetClass):判断被代理对象是不是已经是一个代理对象了
所以总结下来就是:
如果ProxyFactory设置了proxyFactory.setOptimize(true);,或者UserService 是个类,不是接口,或者UserService 没实现接口或只实现了SpringProxy这个接口时就走CGLIB的动态代理。。。
@Component
public class UserService {
public void test(){
System.out.println("test");
}
}
public class Test {
public static void main(String[] args) {
UserService target = new UserService();
ProxyFactory proxyFactory = new ProxyFactory(target);
proxyFactory.setOptimize(true);
}
}