zoukankan      html  css  js  c++  java
  • Java 动态代理的原理

           做开发的都知道,编程语言可以从运行时还是编译时检查分为动态类型和静态类型。对于Java来说,通常认为它是静态的强类型语言,但是因为Java提供反射的机制,也具备了部分动态类型语言的能力。这一节,我们就讲一讲Java的动态代理。

          动态代理是一种用于运行时动态构建代理,动态处理代理方法调用的机制。它首先是一种机制。在设计模式中有一种模式叫做代理模式(Proxy Pattern),和动态代理类似,其中代理可以看作是对调用目标的一个包装,通过代理完成对目标对象的调用。这其实也是一种解耦。

          实现动态代理的机制有很多,比如JDK自身提供的动态代理JDK Proxy(利用Java语言的反射机制),其他方式有ASM,CGLIB<基于ASM>,Javassit等。动态代理机制主要应用有面向切面AOP、拦截器、RPC调用、日志、事务等等。

            我们先来探究JDK Proxy机制<基于反射>----通过接口。新版本也开始结合ASM机制。它涉及到最重要的类和接口就是Proxy和InvocationHandler。先熟悉他们一下。

            Proxy这个类的作用就是用来动态创建一个代理对象的类,它最常用到的方法是newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

     

     InvocationHandler接口只有一个方法,每个动态代理类都必须实现这个接口。

    有了初印象之后,我们再来看看一个简单的JDK Proxy例子。

    CGLIB生成动态代理的机制<基于ASM>---通过类继承:

        通过生成类的子类作为代理对象,它可以在运行期扩展Java类与实现Java接口。

        CGLIB创建某个类A的动态代理类模式是:

              1.   查找A上的所有非final 的public类型的方法定义;

              2.   将这些方法的定义转换成字节码;

              3.   将组成的字节码转换成相应的代理的class对象;

              4.   实现 MethodInterceptor接口,用来处理 对代理类上所有方法的请求(这个接口和JDK动态代理InvocationHandler的功能和角色是一样的)



    顺便说一下Spring AOP使用不同的技术在运行时创建代理:JDK Proxy和CGLIB。

           它的机制是,如果目标类实现了一个或多个接口,那么spring将创建一个实现了每个接口的JDK动态代理。如果目标类没有实现接口,Spring将使用CGLIB动态创建一个新类,它是目标的子类("extends")。这导致一个重要的区别:JDK Proxy无法转为原始的目标类,因为它只是一个动态代理,恰好实现了与目标相同的接口。而CGLIB可以像目标类本身一样。

    JDK Proxy的优势:

          最小化依赖关系;

          平滑进行JDK版本升级,而字节码类库通常需要更新以保证新版本的java使用;

          代码实现简单。

    基于CGLIB框架的优势:

         有的时候调用目标可能不便实现额外接口,从而在运行期扩展Java类与实现Java接口;从某种角度看,限定调用者实现接口是有些侵入性的实践,类似 cglib 动态代理就没有这种限制;

          只操作我们关心的类,而不必管其他相关类;

          高性能。

    欢迎关注本人公众号

  • 相关阅读:
    Service Name Port Number Transport Protocol tcp udp 端口号16bit
    linux linux 互传文件 win 不通过 ftp sftp 往linux 传文件(文件夹)
    soft deletion Google SRE 保障数据完整性的手段
    Taylor series
    Taylor's theorem
    Moving average
    REQUEST
    Unix file types
    mysqld.sock
    Tunneling protocol
  • 原文地址:https://www.cnblogs.com/liamlee/p/9569237.html
Copyright © 2011-2022 走看看