zoukankan      html  css  js  c++  java
  • 总结两种动态代理jdk代理和cglib代理

    动态代理

    上篇文章讲了什么是代理模式,为什么用代理模式,从静态代理过渡到动态代理。

    这里再简单总结一下

    • 什么是代理模式,给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原对象,而是通过代理对象间接地操控原对象。
    • 静态代理是在程序发布之前,我们就必须写好代理类的
    • 动态代理在程序发布之前,并没有写好代理类,而是发布之后,动态创建代理对象的

    这篇文章主要介绍两种动态代理,jdk代理和cglib代理

    jdk代理

    实现

    • 通过实现 InvocationHandler 接口创建自己的调用处理器
    • 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类
    • 通过反射机制获得动态代理类的构造函数
    • 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入

    代码

     Sale saleProxy=(Sale)Proxy.newProxyInstance( jiajun.getClass().getClassLoader(), jiajun.getClass().getInterfaces(), 
        		   new InvocationHandler() { 
        	   			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
        	   			{ 
        	   				System.out.println("===before==="); 
        	   				Object obj = method.invoke(jiajun, args);
        	   				System.out.println("===after==="); return obj; } 
        	   			});
        		    		 
           saleProxy.sale();
           saleProxy.rent();
    

    原理

    • 生成一个代理类,这个代理类继承Proxy类并且实现了我们定义的接口,代理对象调用方法的时候,调用这个代理对象的一个成员InvocationHandler(上面我们传入了一个InvocationHandler实现对象)的方法,也就是我们添加了before和after后的方法。

    cglib代理

    实现

    • 实现CGLib包提供的MethodInterceptor接口,实现intercept方法,用CGLib中的Enhancer的creat方法创建代理对象

    代码

    class CGLibProxy implements MethodInterceptor {
        public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
            System.out.println("Before:" + method);  
            Object object = proxy.invokeSuper(obj, arg);
            System.out.println("After:" + method); 
            return object;
        }
    }
    public class Test2 {
    	public static void main(String[] args) {
    		CGLibProxy cgLibProxy=new CGLibProxy();
    		Jiajun jiajunProxy=(Jiajun)Enhancer.create(Jiajun.class,cgLibProxy);
    		jiajunProxy.buy();
    		jiajunProxy.sale();
    	}
    }
    
    

    原理

    • 通过asm字节码生成框架生成代理类Class的二进制字节码
    • 通过Class.forName加载二进制字节码,生成Class对象
    • 通过反射机制获取实例构造,并初始化代理类对象

    jdk代理 vs cglib代理

    • jdk代理只能代理接口,不能代理没有接口的类。
    • cglib代理可以代理没有接口的类

    总结

    • 动态代理相对于静态代理更加灵活,减少了代码量也提高了可维护性。
    • 动态代理有两种,一种是jdk代理,通过创建一个继承Proxy类并实现接口的代理对象。一种是cglib代理,通过asm生成代理类class的字节码,再生成Class对象,最后通过反射创建代理对象。
    • jdk代理只适合基于接口的代理,cglib可以代理没有实现接口的目标对象。

    我觉得分享是一种精神,分享是我的乐趣所在,不是说我觉得我讲得一定是对的,我讲得可能很多是不对的,但是我希望我讲的东西是我人生的体验和思考,是给很多人反思,也许给你一秒钟、半秒钟,哪怕说一句话有点道理,引发自己内心的感触,这就是我最大的价值。(这是我喜欢的一句话,也是我写博客的初衷)

  • 相关阅读:
    Linux-RedHat 手动创建RAID和LVM分区
    Centos 文件系统 xfs、ext4、ext3 的区别
    CentOS7.5 rpm方式安装MySQL8.0.13
    virtualbox-host-only模式主机能上网虚拟机无法上网的问题解决
    RPA-智能流程自动化解决方案
    论文笔记——Rethinking the Inception Architecture for Computer Vision
    论文笔记——Factorized Convolutional Neural Networks
    论文笔记—Flattened convolution neural networks for feedforward acceleration
    论文笔记——Data-free Parameter Pruning for Deep Neural Networks
    AlexNet网络结构特点总结
  • 原文地址:https://www.cnblogs.com/-new/p/7151136.html
Copyright © 2011-2022 走看看