博客
关于我
面向接口的静态代理和java动态代理
阅读量:786 次
发布时间:2019-03-25

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

静态代理

代理模式概述

代理模式是一种常见的设计模式,其核心思想是在不改变目标对象的情况下,通过引入一个间接对象(代理)来装饰或增强目标对象的功能。这种模式通常用于当我们想对目标对象的某些方法进行额外处理或监控,而不会对原始业务逻辑造成太大影响时。

静态代理实现

在静态代理中,代理类(Proxy)与目标对象(RealObject)之间通常存在继承关系。代理类中包含一个引用(通常是通过构造器设置),这个引用指向目标对象。这样,代理类可以调用目标对象的方法,并在其中插入自己的逻辑。

代码示例
interface Interface {    void doSomething();    void somethingElse(String arg);}class RealObject implements Interface {    @Override    public void doSomething() {        System.out.println("Real doSomething");    }    @Override    public void somethingElse(String arg) {        System.out.println("Real somethingElse " + arg);    }}class SimpleProxy implements Interface {    private Interface proxied;    public SimpleProxy(Interface proxied) {        this.proxied = proxied;    }    @Override    public void doSomething() {        System.out.println("Proxy doSomething before");        proxied.doSomething();        System.out.println("Proxy doSomething after");    }    @Override    public void somethingElse(String arg) {        System.out.println("Proxy somethingElse before");        proxied.somethingElse(arg);        System.out.println("Proxy somethingElse after");    }}class SimpleProxyDemo {    public static void consumer(Interface iface) {        iface.doSomething();        iface.somethingElse("biu biu");    }    public static void main(String[] args) {        consumer(new RealObject()); // 直接调用        System.out.println(" ====== ");        consumer(new SimpleProxy(new RealObject())); // 使用静态代理    }}

静态代理特点

  • 优点:简单易实现,直接在代理方法中添加额外逻辑。
  • 缺点:当目标对象需要对接口进行扩展时,可能需要重新编写所有接口方法,这会导致开发工作量增加,尤其是在接口多变的情况下。

动态代理

动态代理概述

动态代理是一种更灵活的实现代理模式的方式。与静态代理不同,动态代理不需要预先知道目标对象的所有方法,而是在运行时动态地处理方法调用。这种方法通过反射机制实现,能够支持接口的动态扩展。

动态代理实现

动态代理的实现依赖于两个核心组件:

  • InvocationHandler:这个类必须实现InvocationHandler接口,其主要职责是在方法调用前、执行过程中和方法调用后执行自定义逻辑。
  • Proxy.newProxyInstance():使用Java反射API生成动态代理对象,这个过程需要指定目标接口和InvocationHandler。
  • 代码示例
    import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;class DynamicProxyHandler implements InvocationHandler {    private Object proxied;    public DynamicProxyHandler(Object proxied) {        this.proxied = proxied;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("Method: " + method.getName());        System.out.println("Arguments: " + (args != null ? args : ""));        System.out.println("---        try {            return method.invoke(proxied, args);        } catch (Throwable e) {            System.out.println("Error occurred: " + e.getMessage());            throw e;        }        System.out.println("After method execution");        return null;    }}class SimpleDynamicProxy {    public static void consumer(Interface iface) {        iface.doSomething();        iface.somethingElse("biu biu");    }    public static void main(String[] args) {        RealObject real = new RealObject();        consumer(real); // 直接调用        System.out.println(" ============== ");        // 使用动态代理生成代理对象        Interface proxy = (Interface) Proxy.newProxyInstance(            Interface.class.getClassLoader(),             new Class[] { Interface.class },             new DynamicProxyHandler(real)        );        consumer(proxy); // 通过动态代理调用    }}

    动态代理特点

    • 优点:能够灵活地支持任意接口的动态扩展,无需提前知道所有方法。
    • 缺点:反射操作可能影响性能,尤其是在频繁调用方法的情况下。

    两种代理模式的对比

    特性 静态代理 动态代理
    实现方式 通过直接继承接口实现 通过反射和InvocationHandler实现
    方法调用控制 在方法体内直接添加逻辑 在调用处理器中动态处理方法
    接口扩展支持 需要重新实现所有接口方法 支持接口的动态扩展
    代理对象生成方式 使用构造器或工厂类 使用Proxy.newProxyInstance()
    性能影响 有一定的性能开销,但可以预先优化 反射操作会引入额外性能开销

    个人感受

    静态代理和动态代理各有优劣,静态代理简单易懂,适合接口较为稳定和小变动的情况。动态代理则更灵活,适合接口可能发生变化或需要动态扩展功能的情况。作为开发者,根据具体需求选择合适的代理模式至关重要。

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

    你可能感兴趣的文章
    mysql 判断表字段是否存在,然后修改
    查看>>
    MySQL 到底能不能放到 Docker 里跑?
    查看>>
    mysql 前缀索引 命令_11 | Mysql怎么给字符串字段加索引?
    查看>>
    MySQL 加锁处理分析
    查看>>
    mysql 协议的退出命令包及解析
    查看>>
    mysql 参数 innodb_flush_log_at_trx_commit
    查看>>
    mysql 取表中分组之后最新一条数据 分组最新数据 分组取最新数据 分组数据 获取每个分类的最新数据
    查看>>
    MySQL 命令和内置函数
    查看>>
    MySQL 和 PostgreSQL,我到底选择哪个?
    查看>>
    mysql 四种存储引擎
    查看>>
    MySQL 在并发场景下的问题及解决思路
    查看>>
    MySQL 在控制台插入数据时,中文乱码问题的解决
    查看>>
    MySQL 基础架构
    查看>>
    MySQL 基础模块的面试题总结
    查看>>
    MySQL 处理插入重主键唯一键重复值办法
    查看>>
    MySQL 备份 Xtrabackup
    查看>>
    mysql 复杂查询_mysql中复杂查询
    查看>>
    mYSQL 外键约束
    查看>>
    mysql 多个表关联查询查询时间长的问题
    查看>>
    mySQL 多个表求多个count
    查看>>