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 动态代理就没有这种限制;

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

          高性能。

    欢迎关注本人公众号

  • 相关阅读:
    SharePoint 2010 ——自定义上传页面与多文件上传解决方案
    SPJS Upload for SharePoint: Custom upload page for uploading documents to various document libraries in a site collection
    刚刚结束了公司EP流程,开始KMS项目开发了
    小孩出生6个月了,记录一下
    PeopleSoft FSCM Production Support 案例分析之一重大紧急事故发生时的应对策略
    PeopleSoft FSCM Production Support 案例分析
    SQL Server数据库常用的T-SQL命令
    详细讲解删除SQL Server日志的具体方法
    year()+month() 不错的Idear
    input只能输入数字
  • 原文地址:https://www.cnblogs.com/liamlee/p/9569237.html
Copyright © 2011-2022 走看看