博客
关于我
面向接口的静态代理和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/

    你可能感兴趣的文章
    MSCRM调用外部JS文件
    查看>>
    MSEdgeDriver (Chromium) 不适用于版本 >= 79.0.313 (Canary)
    查看>>
    MsEdgeTTS开源项目使用教程
    查看>>
    msf
    查看>>
    MSP430F149学习之路——SPI
    查看>>
    msp430入门编程45
    查看>>
    MSSQL数据库查询优化(一)
    查看>>
    MSSQL数据库迁移到Oracle(二)
    查看>>
    MSSQL日期格式转换函数(使用CONVERT)
    查看>>
    MSTP多生成树协议(第二课)
    查看>>
    MSTP是什么?有哪些专有名词?
    查看>>
    Mstsc 远程桌面链接 And 网络映射
    查看>>
    Myeclipse常用快捷键
    查看>>
    MyEclipse更改项目名web发布名字不改问题
    查看>>
    MyEclipse用(JDBC)连接SQL出现的问题~
    查看>>
    mt-datetime-picker type="date" 时间格式 bug
    查看>>
    myeclipse的新建severlet不见解决方法
    查看>>
    MyEclipse设置当前行背景颜色、选中单词前景色、背景色
    查看>>
    Mtab书签导航程序 LinkStore/getIcon SQL注入漏洞复现
    查看>>
    myeclipse配置springmvc教程
    查看>>