Spring中JDK动态代理和Cglib代理的区别

    Spring的AOP基于代理模式,而且它即便用到了JDK动态代理也使用了Cglib代理。java

    以下代码是springAOP中默认的代理实现类DefaultAopProxyFactory,其中建立代理的方法createAopProxy,在这个方法中Spring经过判断targetClass是否有实现接口来肯定使用哪种代理,若是实现了接口则使用JDK动态代理,若是没有实现接口则使用Cglib代理。同时JdkDynamicAopProxy为JDK动态代理的生成类,ObjenesisCglibAopProxy能够生成Cglib代理。spring

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
    public DefaultAopProxyFactory() {
    }

	//建立代理
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
            return new JdkDynamicAopProxy(config);//生成JDK动态代理
        } else {
            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.");
            } else {//ObjenesisCglibAopProxy生成Cglib代理
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
            }
        }
    }

    private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
        Class<?>[] ifcs = config.getProxiedInterfaces();
        return ifcs.length == 0 || ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]);
    }
}

    从上面代码能够发现当须要被代理的类实现了接口的时候Spring会使用动态代理,当被代理的类没有接口实现的时候使用的是Cglib,咱们也能够强制使用CGlib,在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>。框架

    性能问题:因为Cglib代理是利用ASM字节码生成框架在内存中生成一个须要被代理类的子类完成代理,而JDK动态代理是利用反射原理完成动态代理,因此Cglib建立的动态代理对象性能比JDk动态代理动态建立出来的代理对象新能要好的多,可是对象建立的速度比JDk动态代理要慢,因此,当Spring使用的是单例状况下能够选用Cglib代理,反之使用JDK动态代理更加合适。同时还有一个问题,被final修饰的类只能使用JDK动态代理,由于被final修饰的类不能被继承,而Cglib则是利用的继承原理实现代理的。性能

关于动态代理请参考:https://my.oschina.net/zicheng/blog/1920396ui

相关文章
相关标签/搜索