Spring AOP源码阅读:如何判定是否可以使用JDK动态代理

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.
    *
    * 

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动态代理:

  1. 代理的是接口
  2. 代理的是使用了JDK动态代理的代理类。

你可能感兴趣的:(Spring,FrameWork,java,jdk,aop,spring)