• Java中如何实现代理机制(JDK动态代理和cglib动态代理)


    http://blog.csdn.net/skiof007/article/details/52806714

    JDK动态代理:代理类和目标类实现了共同的接口,用到InvocationHandler接口
    CGLIB动态代理:代理类是目标类的子类,用到MethodInterceptor接口。

    jdk动态代理是由Java内部的反射机制来实现的;cglib动态代理底层则是借助asm来实现的。

    总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。由此可以看出,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。。

    Java字节码生成开源框架介绍--ASM:

    ASM 是一个 Java 字节码操控框架。它能够以二进制形式修改已有类或者动态生成类。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。

    过ASM在创建class字节码的过程中,操纵的级别是底层JVM的汇编指令级别,这要求ASM使用者要对class组织结构和JVM汇编指令有一定的了解。

    InvocationHandler角色的由来

    有上图可以看出,代理类处理的逻辑很简单:在调用某个方法前及方法后做一些额外的业务。换一种思路就是:在触发(invoke)真实角色的方法之前或者之后做一些额外的业务。那么,为了构造出具有通用性和简单性的代理类,可以将所有的触发真实角色动作交给一个触发的管理器,让这个管理器统一地管理触发。这种管理器就是Invocation Handler。
      动态代理模式的结构跟上面的静态代理模式稍微有所不同,多引入了一个InvocationHandler角色。
      先解释一下InvocationHandler的作用:
      在静态代理中,代理Proxy中的方法,都指定了调用了特定的realSubject中的对应的方法,在上面的静态代理模式下,Proxy所做的事情,无非是调用在不同的request时,调用触发realSubject对应的方法;更抽象点看,Proxy所作的事情;在Java中 方法(Method)也是作为一个对象来看待了,动态代理工作的基本模式就是将自己的方法功能的实现交给 InvocationHandler角色,外界对Proxy角色中的每一个方法的调用,Proxy角色都会交给InvocationHandler来处理,而InvocationHandler则调用具体对象角色的方法。如下图所示:

    在这种模式之中:代理Proxy 和RealSubject 应该实现相同的功能,这一点相当重要。(我这里说的功能,可以理解为某个类的public方法)
      在面向对象的编程之中,如果我们想要约定Proxy 和RealSubject可以实现相同的功能,有两种方式:
      a.一个比较直观的方式,就是定义一个功能接口,然后让Proxy 和RealSubject来实现这个接口。
      b.还有比较隐晦的方式,就是通过继承。因为如果Proxy 继承自RealSubject,这样Proxy则拥有了RealSubject的功能,Proxy还可以通过重写RealSubject中的方法,来实现多态。
    其中JDK中提供的创建动态代理的机制,是以a 这种思路设计的,而cglib 则是以b思路设计的。

     JDK的动态代理创建机制----通过接口

    比如现在想为RealSubject这个类创建一个动态代理对象,JDK主要会做以下工作:
      1.获取RealSubject上的所有接口列表;
      2.确定要生成的代理类的类名,默认为:com.sun.proxy.$ProxyXXXX ;
      3.根据需要实现的接口信息,在代码中动态创建该Proxy类的字节码;
      4.将对应的字节码转换为对应的class 对象;
      5.创建InvocationHandler实例handler,用来处理Proxy所有方法调用;
      6.Proxy的class对象以创建的handler对象为参数,实例化一个proxy对象。

      JDK通过java.lang.reflect.Proxy包来支持动态代理,一般情况下,我们使用下面的newProxyInstance方法。

     cglib(Code Generation Library) 生成动态代理类的机制----通过类继承

    cglib是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。

    cglib 创建某个类A的动态代理类的模式是:
      1.查找A上的所有非final 的public类型的方法定义;
      2.将这些方法的定义转换成字节码;
      3.将组成的字节码转换成相应的代理的class对象;
      4.实现 MethodInterceptor接口,用来处理 对代理类上所有方法的请求(这个接口和JDK动态代理InvocationHandler的功能和角色是一样的)

  • 相关阅读:
    hdu 5723 Abandoned country 最小生成树 期望
    OpenJ_POJ C16G Challenge Your Template 迪杰斯特拉
    OpenJ_POJ C16D Extracurricular Sports 打表找规律
    OpenJ_POJ C16B Robot Game 打表找规律
    CCCC 成都信息工程大学游记
    UVALive 6893 The Big Painting hash
    UVALive 6889 City Park 并查集
    UVALive 6888 Ricochet Robots bfs
    UVALive 6886 Golf Bot FFT
    UVALive 6885 Flowery Trails 最短路
  • 原文地址:https://www.cnblogs.com/wangleBlogs/p/7360387.html
Copyright © 2020-2023  润新知