Spring动态代理选择逻辑代码是如何实现的

Spring的动态代理支持cglib和jdk两种代理模式。对于两种动态代理的选择我们通常会说,当一个类实现了接口,Spring会使用jdk代理模式,否则使用cglib的代理模式。因为jdk代理要求一个类必须实现接口,而cglib代理可以将目标类当做父类来实现代理逻辑。但Spring具体在代码层级上是如何实现选择逻辑的呢?我们来看一下,先看一个类

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

	@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);
		}
	}

	/**
	 * Determine whether the supplied {@link AdvisedSupport} has only the
	 * {@link org.springframework.aop.SpringProxy} interface specified
	 * (or no proxy interfaces specified at all).
	 */
	private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
		Class<?>[] ifcs = config.getProxiedInterfaces();
		return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
	}

}

这个类就是用来创建代理的,在它的createAopProxy方法中实现了对cglib代理(ObjenesisCglibAopProxy)和jdk代理(JdkDynamicAopProxy)的选择。代码逻辑比较简单,对我们分析问题有用的是两个if判断,即

if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {

if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {

第一个if是基于传入参数AdvisedSupport的配置信息来判断是创建cglib代理还是jdk代理。我们看下AdvisedSupport类的类图

AdvisedSupport继承自ProxyConfig。类如其名,ProxyConfig是用来管理代理的一些配置属性,包括下面的五种

private boolean proxyTargetClass = false;

private boolean optimize = false;

boolean opaque = false;

boolean exposeProxy = false;

private boolean frozen = false;

结合if条件和配置属性,我们来看具体的选择逻辑

1、满足配置optimize为false,proxyTargetClass为false,并且目标类没有实现接口或者目标类实现了一个接口,但该接口为SpringProxy的子接口,则创建jdk代理

2、不满足条件1,但目标类为接口或者目标类为代理类(Proxy类的子类),则创建jdk代理

3、不满足条件1、2,则创建cglib代理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值