CGLIB 和 JDK生成动态代理类的区别

 我来答
尚学堂科技有限公司
2017-01-18 · 百度知道合伙人官方认证企业
尚学堂科技有限公司
北京尚学堂科技有限公司是一家从事JAVA、大数据、web前端、网络在线教育、互联网架构师、Android、ios技术开发、咨询为一体的软件公司。公司由海外留学人员和国内IT人士创建。
向TA提问
展开全部

CGLIB 和 JDK生成动态代理类区别

  • jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。

  • cglib这种第三方类库实现的动态代理应用更加广泛,并不需要目标类基于统一的接口,且在效率上更有优势。

下面分别用2个具体例子来详细阐述

jdk生成代理类

  1. 为目标类(target)定义统一的接口类Service,这个是jdk动态代理必须的前提



    public interface Service {  
        /** 
         * add方法 
         */  
        public void add();  
      
        /** 
         * update方法 
         */  
        public void update();  
    }


2.目标类AService

public class AService implements Service {  
    /* 
     * (non-Javadoc) 
     *  
     * @see jdkproxy.Service#add() 
     */  
    public void add() {  
        System.out.println("AService add>>>>>>>>>>>>>>>>>>");  
    }  
  
    /* 
     * (non-Javadoc) 
     *  
     * @see jdkproxy.Service#update() 
     */  
    public void update() {  
        System.out.println("AService update>>>>>>>>>>>>>>>");  
    }  
}

3.实现动态代理类MyInvocationHandler,实现InvocationHandler接口,并且实现接口中的invoke方法。在
invoke方法中加入一些代理功能。目标类方法的执行是由mehod.invoke(target,args)这条语句完成。

public class MyInvocationHandler implements InvocationHandler {  
    private Object target;  
  
    MyInvocationHandler() {  
        super();  
    }  
  
    MyInvocationHandler(Object target) {  
        super();  
        this.target = target;  
    }  
  
    public Object invoke(Object proxy, Method method, Object[] args)  
            throws Throwable {  
        // 程序执行前加入逻辑,MethodBeforeAdviceInterceptor  
        System.out.println("before-----------------------------");  
        // 程序执行  
        Object result = method.invoke(target, args);  
        // 程序执行后加入逻辑,MethodAfterAdviceInterceptor  
        System.out.println("after------------------------------");  
        return result;  
    }  
}

4.测试类,其中增强的目标对象是由Proxy.newProxyInstance(aService.getClass().getClassLoader(), aService.getClass().getInterfaces(), handler);来生成的。

public class Test {  
    public static void main(String[] args) {  
        Service aService = new AService();  
        MyInvocationHandler handler = new MyInvocationHandler(aService);  
        // Proxy为InvocationHandler实现类动态创建一个符合某一接口的代理实例  
        Service aServiceProxy = (Service) Proxy.newProxyInstance(aService  
                .getClass().getClassLoader(), aService.getClass()  
                .getInterfaces(), handler);  
        // 由动态生成的代理对象来aServiceProxy 代理执行程序,其中aServiceProxy 符合Service接口  
        aServiceProxy.add();  
        System.out.println();  
        aServiceProxy.update();
        }

cglib动态代理实现AOP拦截

  1. 被代理目标类,cglib不需要目标类实现接口



    public class Base {  
        /** 
         * 一个模拟的add方法 
         */  
        public void add() {  
            System.out.println("add ------------");  
        }  
    }
  2. 实现动态代理类CglibProxy,需要实现MethodInterceptor接口,实现intercept方法。

    public class CglibProxy implements MethodInterceptor {  
      
        public Object intercept(Object object, Method method, Object[] args,  
                MethodProxy proxy) throws Throwable {  
            // 添加切面逻辑(advise),此处是在目标类代码执行之前,即为MethodBeforeAdviceInterceptor。  
            System.out.println("before-------------");  
            // 执行目标类add方法  
            proxy.invokeSuper(object, args);  
            // 添加切面逻辑(advise),此处是在目标类代码执行之后,即为MethodAfterAdviceInterceptor。  
            System.out.println("after--------------");  
            return null;  
        }  
      
    }
  3. 获取增强的目标类的工厂Factory,其中增强的方法类对象是有Enhancer来实现的

    public class Factory {  
        /** 
         * 获得增强之后的目标类,即添加了切入逻辑advice之后的目标类 
         *  
         * @param proxy 
         * @return 
         */  
        public static Base getInstance(CglibProxy proxy) {  
            Enhancer enhancer = new Enhancer();  
            enhancer.setSuperclass(Base.class);  
            //回调方法的参数为代理类对象CglibProxy,最后增强目标类调用的是代理类对象CglibProxy中的intercept方法  
            enhancer.setCallback(proxy);  
            // 此刻,base不是单纯的目标类,而是增强过的目标类  
            Base base = (Base) enhancer.create();  
            return base;  
        }  
    }
  4. 测试类

    public class Test {  
        public static void main(String[] args) {  
            CglibProxy proxy = new CglibProxy();  
            // base为生成的增强过的目标类  
            Base base = Factory.getInstance(proxy);  
            base.add();  
        }  
    }



    从上面2个例子,可看出cglib中目标类Base并没有实现接口,而jdk生成代理类例子中AService 实现了Service接口,所以CGLIB 和 JDK生成动态代理类的区别最大的区别就是目标类是否需要实现接口。

Storm代理
2023-08-29 广告
"StormProxies是全球大数据IP资源服务商,其住宅代理网络由真实的家庭住宅IP组成,可为企业或个人提供满足各种场景的代理产品。点击免费测试(注册即送1G流量)StormProxies有哪些优势?1、IP+端口提取形式,不限带宽,I... 点击进入详情页
本回答由Storm代理提供
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式