java动态代理动态在哪里?

作者: 工程师milter | 来源:发表于2018-06-23 22:55 被阅读190次

    最近在学习spring,其中大量使用了动态代理技术来增强Bean的功能。所以有必要捋一捋动态代理。

    1、代理

    代理是一种经典的设计模式,访问控制、远程过程调用、AOP都是使用代理的场景。如果对这种设计模式不熟悉,建议参考《Java设计模式》的第11章,里面也有动态代理的内容。

    2、java 的动态代理动态在哪里?

    我们一般创建代理时的顺序是:

    • 知道要代理谁,假设为A
    • 创建代理对象,假设为B,继承A,并让B持有A的一个实例。
    • 让B实现与A相同的public方法,在里面调用A对应的方法,此时可以做很多文章,比如打log,验证参数等,这些行为是我们创建代理的核心目的,毕竟代理不是简单的传声筒。我们暂且将这些行为称为代理目的

    动态代理是反过来的,它是首先知道代理目的,据此实现一个类H,将代理目的的相关代码写进去。这个类H要有一个Object 类型的成员,用来表示要代理的对象。用Object,表示可以代理任何对象。
    然后,实例化类H,传入要代理的具体对象,生成h对象,将h对象和要代理原对象哪些public方法的信息(通过提供接口的方式)一起交给另一个类Proxy,Proxy会根据public方法的信息和h对象揉和在一起生成一个代理类$Proxy,并同时实例化该类,生成proxy对象,这个proxy就跟我们按照传统方式手写的代理对象是一样的。

    可见,所谓动态,在于真正的代理类是在程序运行的时候由Proxy这个牛叉的类生成的。类生成类就是字节码生成技术。这个牛叉的类只需要告诉它代理原对象的哪些public方法(通过接口的形式)和具体的代理行为,即h对象,就可以work了。

    H其实就是实现java.lang.reflect.InvocationHandler接口的类。该接口的方法invoke就是我们填写代理目的代码的地方。
    Proxy类其实就是java.lang.reflect.Proxy。该类有一个静态方法newProxyInstance,就是接收h对象和要代理原对象哪些pubic方法的地方。

    3、局限性

    java动态代理的局限性在于,我们告诉Proxy要代理哪些方法时,只能通过原对象实现的接口的方式。就是说,原对象那些不是实现接口的public方法,是没办法通过这种技术来代理的。所以才有了CGLIB这种技术。

    4、没有例子吗?

    http://www.importnew.com/27772.html 这里有。
    之前推荐的《Java设计模式》中也有。
    《深入理解Java虚拟机》中也有。应该够了。
    本文的目的在于总结自己对于动态代理的理解,嗯,好像达到了。

    相关文章

      网友评论

        本文标题:java动态代理动态在哪里?

        本文链接:https://www.haomeiwen.com/subject/ynbdyftx.html