动态代理

作者: 雪驹 | 来源:发表于2017-03-07 23:00 被阅读0次

动态代理可以在不改动原代码的前提下,为其添加验权、事务控制、日志打印等功能。

例如,统计某方法运行所消耗的时间。通常做法如下:

// 记录此方法的开始时间(动态代理模式下,这部分不在此方法中实现)
// 处理业务
// 记录此方法的结束时间并打印(动态代理模式下,这部分不在此方法中实现)

在动态代理里,时间统计代码写在了代理模块里。将业务代码和时间统计代码完全解耦了。

动态代理有两种实现方式,一种是调用 JDK。另一种是使用 Cglib,两者的区别是Cglib是可以不需要接口。

就上面伪代码的例子。如果用代理模式,应该如何做呢?下面就是我用代码完成的一个示例及相关说明。

用调用JDK的方式实现动态代理,有这么几个类:
1、JDK 实现的 Proxy 类。此类的 newProxyInstance 方法用来生成代理对象。需要 InvocationHandler 的实例和目标代码类的字节码作为参数。
2、实现 InvocationHandler 接口的类,这个类通过实现InvocationHandler 接口的 invoke 方法,将「代理的代码」注入到「目标代码」中。而 createProxyIntance 方法用目标对象字节码和 handler(此类)以反射的方式生成代理对象。

public class RemindHandler implements InvocationHandler {
    
    /** 要注入的目标对象 */
    private Object target;
    
    public Object createProxyIntance(Object target) {
        this.target = target;
        Class<?> clazz = this.target.getClass();// 目标对象的字节码
        
        // 通过目标对象字节码和 handler(此类)以反射的方式生成代理对象。
        Object object = Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
        return object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("学习之前,提醒自己做好学习计划。");
        method.invoke(target);
        System.out.println("学习之后,提醒自己及时总结,做笔记,自测。");
        return null;
    }
}

3、目标代码类,对目标代码的具体事务进行实现。

public class StudyEnglish implements Study{

    @Override
    public void startReading() {
        System.out.println("阅读英语教材中...");
    }

}

4、目标代码类的接口类。

public interface Study {
    public void startReading();
}

下面是对以上代码进行测试的代码

public static void main(String args[]){
        StudyEnglish study = new StudyEnglish();
        RemindHandler handler = new RemindHandler();
        Study s = (Study) handler.createProxyIntance(study);
        s.startReading();
    }
}

一句话总结就是,动态代理通过被代理类的字节码和注入的代码(日志,权限,事务),以反射的方式生成一个代理的对象。

备注1:代理模式中,日志、验权、事务等代码是可复用的,不变的代码,在项目中大部分属于技术代码。而被代理的代码,大部分属于变化的业务代码。

备注2:动态代理需要注意的一个点
Spring事务处理时自我调用的解决方案及一些实现方式的风险

相关文章

  • 面试系列~动态代理实现与原理

    动态代理有JDK动态代理, CGLIB动态代理, SpringAOP动态代理 一,JDK动态代理  jdk动态代理...

  • 编程常用的设计模式

    动态代理和静态代理 静态代理 动态代理 静态代理与动态代理的区别 JDK中的动态代理和CGLIB 实现动态代理的方...

  • Spring的AOP原理分析

    一 动态代理 动态代理分为JDK动态代理和CGLIB动态代理 jdk动态代理 被代理类(目标类)和代理类必须实现同...

  • 设计模式之代理模式

    代理分为静态代理和动态代理。 动态代理又包括基于JDK的动态代理、基于CGlib 的动态代理、基于Aspectj实...

  • Java高级主题(五)——动态代理

    代理可以分为静态代理、动态代理,动态代理又可以分为 jvm的动态代理 和 cglib的动态代理。像spring框架...

  • 动态代理

    动态代理分为两类:1、基于接口的动态代理; (JDK动态代理 )2、基于类的动态代理;(cglib动态代理)3、J...

  • 动态代理的两种方式

    静态代理就不说了,基本用到的都是动态代理。 Java中动态代理有JDK动态代理和CGLIB动态代理。 JDK代理的...

  • Java动态代理

    通过以下几种方式介绍动态代理 动态代理涉及到的类 动态代理用法 Proxy类解析 动态代理类解析 动态代理涉及到的...

  • Spring之代理模式

    九、代理模式 目录:静态代理、动态代理AOP的底层机制就是动态代理。代理模式分为静态代理和动态代理。接触aop之前...

  • Java 代理

    静态代理 动态代理 动态代理, 日志切片使用反射获得方法 动态代理, 自定义注解(对注解的方法,使用动态代理添加切...

网友评论

    本文标题:动态代理

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