Java代理模式实例代码分析

发布时间:2022-04-01 09:11:10 作者:iii
来源:亿速云 阅读:137

Java代理模式实例代码分析

1. 代理模式概述

代理模式(Proxy Pattern)是Java中常用的设计模式之一,属于结构型模式。它通过创建一个代理对象来控制对目标对象的访问,从而在不改变目标对象的情况下,增强或修改其行为。代理模式的核心思想是为其他对象提供一个代理,并由代理对象控制对原对象的引用。

代理模式的主要应用场景包括: - 远程代理:为远程对象提供本地代理,隐藏网络通信细节。 - 虚拟代理:延迟创建开销较大的对象,直到真正需要时才创建。 - 保护代理:控制对敏感对象的访问权限。 - 智能引用代理:在访问对象时执行额外的操作,如记录日志、缓存等。

代理模式的结构通常包括以下角色: - Subject(抽象主题):定义目标对象和代理对象的共同接口。 - RealSubject(真实主题):实现抽象主题接口,是代理模式中的目标对象。 - Proxy(代理):实现抽象主题接口,并持有对真实主题的引用,负责控制对真实主题的访问。


2. 静态代理

静态代理是最简单的代理模式实现方式。在静态代理中,代理类和目标类都实现相同的接口,代理类通过持有目标类的实例来调用目标类的方法,并在调用前后添加额外的逻辑。

2.1 静态代理示例代码

以下是一个静态代理的示例代码:

// 抽象主题接口
interface Subject {
    void request();
}

// 真实主题类
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

// 代理类
class Proxy implements Subject {
    private RealSubject realSubject;

    public Proxy(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public void request() {
        // 前置处理
        System.out.println("Proxy: Pre-processing request.");
        
        // 调用真实主题的方法
        realSubject.request();
        
        // 后置处理
        System.out.println("Proxy: Post-processing request.");
    }
}

// 客户端代码
public class StaticProxyDemo {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        Proxy proxy = new Proxy(realSubject);
        proxy.request();
    }
}

2.2 静态代理分析


3. 动态代理

动态代理是Java中更灵活的代理模式实现方式。与静态代理不同,动态代理在运行时动态生成代理类,无需手动编写代理类。Java提供了两种动态代理机制:基于接口的JDK动态代理和基于类的CGLIB动态代理。

3.1 JDK动态代理

JDK动态代理是Java标准库提供的动态代理实现方式。它基于接口生成代理类,因此目标类必须实现至少一个接口。

3.1.1 JDK动态代理示例代码

以下是一个JDK动态代理的示例代码:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 抽象主题接口
interface Subject {
    void request();
}

// 真实主题类
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

// 动态代理处理器
class DynamicProxyHandler implements InvocationHandler {
    private Object target;

    public DynamicProxyHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 前置处理
        System.out.println("DynamicProxy: Pre-processing request.");
        
        // 调用目标对象的方法
        Object result = method.invoke(target, args);
        
        // 后置处理
        System.out.println("DynamicProxy: Post-processing request.");
        
        return result;
    }
}

// 客户端代码
public class JDKDynamicProxyDemo {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        Subject proxy = (Subject) Proxy.newProxyInstance(
            realSubject.getClass().getClassLoader(),
            realSubject.getClass().getInterfaces(),
            new DynamicProxyHandler(realSubject)
        );
        proxy.request();
    }
}

3.1.2 JDK动态代理分析

3.2 CGLIB动态代理

CGLIB(Code Generation Library)是一个强大的代码生成库,可以在运行时动态生成类的子类作为代理类。与JDK动态代理不同,CGLIB可以代理没有实现接口的类。

3.2.1 CGLIB动态代理示例代码

以下是一个CGLIB动态代理的示例代码:

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

// 真实主题类
class RealSubject {
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

// 动态代理拦截器
class CglibProxyInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        // 前置处理
        System.out.println("CglibProxy: Pre-processing request.");
        
        // 调用目标对象的方法
        Object result = proxy.invokeSuper(obj, args);
        
        // 后置处理
        System.out.println("CglibProxy: Post-processing request.");
        
        return result;
    }
}

// 客户端代码
public class CglibDynamicProxyDemo {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(RealSubject.class);
        enhancer.setCallback(new CglibProxyInterceptor());
        
        RealSubject proxy = (RealSubject) enhancer.create();
        proxy.request();
    }
}

3.2.2 CGLIB动态代理分析


4. 代理模式的应用场景

代理模式在实际开发中有广泛的应用,以下是一些常见的应用场景:

4.1 远程代理

远程代理用于隐藏网络通信细节,客户端通过代理对象访问远程服务。例如,Java RMI(远程方法调用)就是基于远程代理实现的。

4.2 虚拟代理

虚拟代理用于延迟创建开销较大的对象。例如,在加载大图片时,可以使用虚拟代理先显示缩略图,等真正需要时再加载完整图片。

4.3 保护代理

保护代理用于控制对敏感对象的访问权限。例如,在权限管理系统中,只有具有特定权限的用户才能访问某些资源。

4.4 智能引用代理

智能引用代理用于在访问对象时执行额外的操作。例如,在访问数据库时,可以使用代理对象记录日志或缓存查询结果。


5. 总结

代理模式是一种强大的设计模式,通过引入代理对象,可以在不修改目标对象的情况下增强或修改其行为。静态代理实现简单,但灵活性较差;动态代理(JDK和CGLIB)则提供了更高的灵活性,适用于复杂的应用场景。

在实际开发中,应根据具体需求选择合适的代理模式实现方式。如果需要代理接口,可以选择JDK动态代理;如果需要代理类,可以选择CGLIB动态代理。通过合理使用代理模式,可以提高代码的可维护性和扩展性。

推荐阅读:
  1. java代理模式实例分析
  2. java动态代理实例代码分析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:pentaho工具将数据库数据导入导出为Excel图文的方法

下一篇:Swift中类与结构的初始化方法

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》