美文网首页
5分钟弄懂动态代理

5分钟弄懂动态代理

作者: landscape_f117 | 来源:发表于2020-05-03 20:59 被阅读0次

    代理模式

    用途:控制对象的访问,或者增强对象功能
    简单来说就是代理对象通过组合的方式获得被代理对象,且实现相同接口。在执行接口方法时,增加一些操作,并调用被代理对象的方法。
    代理模式分为静态代理和动态代理。静态代理是程序员手动编写代理类,动态代理则是在程序运行期间动态生成代理类。由于静态代理违反了开闭原则,所以需要引入动态代理。

    动态代理

    动态代理有两种实现方式,一种是JDK方式,一种是CGLIB方式。

    JDK方式

    核心是java.lang.reflect中的Proxy类,和InvocationHandler接口。

    一般使用流程是程序员通过注解标记需要被代理的类,之后框架在处理注解时通过Proxy类中的newProxyInstance静态方法生成代理类的对象(在内存中先生成字节码文件,再生成对象)。

       public static Object newProxyInstance(ClassLoader loader,
                                              Class<?>[] interfaces,
                                              InvocationHandler h)
            throws IllegalArgumentException
    

    该方法有三个参数:
    loader是被代理类的类加载器,用来确认当前的代理缓存上下文。(如果已经有代理类,不会重新生成)
    interfaces是被代理类实现的接口。
    h 就是实现了InvocationHandler的对象,其通过重新InvocationHandler对象的Invoke方法表明特定的增强操作(如事务)。

        public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable;
    

    生成的代理对象会替代被代理对象来执行对应的方法。

    示例 可参考SrpingAop中实现InvocationHandler的对象org.springframework.aop.framework.JdkDynamicAopProxy.class

    CGLIB方式

    CGLIB主要解决JDK动态代理只能对接口实现类进行代理的问题。主要用字节码动态编辑的方式生成被代理类的子类对象作为代理类。

    CGLIB 原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。
    CGLIB 底层:使用字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
    CGLIB缺点:对于final方法,无法进行代理。

    相关文章

      网友评论

          本文标题:5分钟弄懂动态代理

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