博客
关于我
Java--代理
阅读量:285 次
发布时间:2019-03-01

本文共 3613 字,大约阅读时间需要 12 分钟。

Java动态代理详解

代理的概念

代理是一种常见的设计模式,旨在在不修改源代码的情况下对目标类的方法进行增强或扩展。在Java中,代理可以分为静态代理和动态代理两种形式。本文将重点介绍动态代理的实现方式及其应用场景。


动态代理的实现原理

动态代理通过Proxy.newProxyInstance方法来创建接口代理对象。该方法的三个主要参数如下:

  • ClassLoader loader:指定用于加载代理类的类加载器。
  • Class<?>[] interfaces:指定被代理接口的类数组。
  • InvocationHandler h:指定一个动态代理的调用处理器(Invocation Handler),用于动态地处理被代理方法的调用。
  • 通过InvocationHandler,我们可以在不修改目标类源代码的情况下,动态地增强目标类的方法行为。


    动态代理的实现步骤

    1. 创建被代理接口

    假设我们有一个接口OneDao,其中定义了一个方法add(int a, int b)用于计算两个整数的和。以下是接口的定义:

    public interface OneDao {    public int add(int a, int b);}

    2. 创建被代理实现类

    接下来,我们创建一个实现OneDao接口的类OneDaoImpl。该类的实现如下:

    public class OneDaoImpl implements OneDao {    @Override    public int add(int a, int b) {        return a + b;    }}

    3. 定义Invocation Handler

    为了实现动态代理,我们需要定义一个InvocationHandler的实现类MyHandler。该类将负责动态地处理被代理方法的调用。以下是MyHandler的实现:

    class MyHandler implements InvocationHandler {    private Object object; // 被代理对象    public MyHandler(Object object) {        this.object = object;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("方法前:" + method.getName());        Object result = method.invoke(object, args);        System.out.println("方法后:" + method.getName());        return result;    }}

    4. 创建代理对象

    通过Proxy.newProxyInstance方法,我们可以根据指定的接口和调用处理器创建一个动态代理对象。以下是创建代理对象的代码示例:

    @Testpublic void method() {    OneDaoImpl oneDao = new OneDaoImpl();    OneDao dao = (OneDao) Proxy.newProxyInstance(OneDaoImpl.class.getClassLoader(),         new Class[]{OneDaoImpl.class},         new MyHandler(oneDao)    );    int add = dao.add(1, 2);    System.out.println(add);}

    5. 调用代理对象

    通过上述代码,我们可以看到动态代理对象dao实际上是通过MyHandler来调用OneDaoImpl类的方法。每当调用dao.add(1, 2)时,MyHandler都会先输出日志,执行目标方法oneDao.add(1, 2),然后再输出日志。


    动态代理的优势

    动态代理的主要优势在于它能够在不修改目标类源代码的情况下,动态地增强目标类的方法行为。这种特性在以下场景尤为有用:

  • 日志记录:可以在方法执行前后记录日志。
  • 性能监控:可以在方法执行过程中监控性能参数。
  • 安全性:可以在方法执行前后进行权限检查或其他安全验证。
  • 功能扩展:可以在不修改目标类的情况下,扩展方法功能。

  • 实际应用示例

    假设我们有一个Human接口,定义了两个方法getAge()getName()。我们可以通过动态代理来增强这些方法的行为。

    被代理类

    public class GDPeople implements Human {    private int age;    private String name;    public GDPeople(int age, String name) {        this.age = age;        this.name = name;    }    @Override    public int getAge() {        return age;    }    @Override    public String getName() {        return name;    }}

    代理工厂

    我们可以创建一个ProxyFactory工厂类,用于生成动态代理对象。以下是ProxyFactory的实现:

    public class ProxyFactory {    public static Object getProxyInstance(Object obj) {        MyInvocationHandler handler = new MyInvocationHandler();        handler.bind(obj);        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),             obj.getClass().getInterfaces(),             handler        );    }}class MyInvocationHandler implements InvocationHandler {    private Object object;    public void bind(Object object) {        this.object = object;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("代理之前:" + method.getName());        Object result = method.invoke(object, args);        System.out.println("代理之后:" + method.getName());        return result;    }}

    使用示例

    public class ProxyTest {    public static void main(String[] args) {        GDPeople gdPeople = new GDPeople(15, "Tom");        Human proxyInstance = (Human) ProxyFactory.getProxyInstance(gdPeople);        int age = proxyInstance.getAge();        String name = proxyInstance.getName();        System.out.println("name:" + name + "-----age:" + age);    }}

    输出结果

    运行上述代码,输出结果如下:

    name:Tom-----age:15

    总结

    通过本文的详细分析和代码示例,我们可以看到动态代理是一种强大的设计模式,能够在不修改目标类源代码的情况下,动态地增强目标类的方法行为。在实际应用中,动态代理广泛应用于日志记录、性能监控、安全性验证等场景。

    转载地址:http://chca.baihongyu.com/

    你可能感兴趣的文章
    NPOI
    查看>>
    NPOI之Excel——合并单元格、设置样式、输入公式
    查看>>
    NPOI初级教程
    查看>>
    NPOI利用多任务模式分批写入多个Excel
    查看>>
    NPOI在Excel中插入图片
    查看>>
    NPOI将某个程序段耗时插入Excel
    查看>>
    NPOI格式设置
    查看>>
    NPOI设置单元格格式
    查看>>
    Npp删除选中行的Macro录制方式
    查看>>
    NR,NF,FNR
    查看>>
    nrf24l01+arduino
    查看>>
    nrf开发笔记一开发软件
    查看>>
    nrm —— 快速切换 NPM 源 (附带测速功能)
    查看>>
    nrm报错 [ERR_INVALID_ARG_TYPE]
    查看>>
    NS3 IP首部校验和
    查看>>
    NSDateFormatter的替代方法
    查看>>
    NSError 的使用方法
    查看>>
    NSGA-Ⅲ源代码
    查看>>
    nsis 安装脚本示例(转)
    查看>>
    NSJSON的用法(oc系统自带的解析方法)
    查看>>