Spring源码阅读1 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.
    *
    * <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动态代理:

  1. 代理的是接口
  2. 代理的是使用了JDK动态代理的代理类。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值