Java中静态代理和动态代理设计模式应用实例举例?

静态代理实例

假设我们有一个需求,要记录一个服务接口IService的所有方法调用的开始和结束时间,以此来监控服务的性能。我们可以使用静态代理模式来实现这个需求。

1. 定义服务接口 IService.java:

复制代码

Java

复制代码
1public interface IService {
2    void serve();
3}

2. 实现服务接口的类 RealService.java:

复制代码

Java

复制代码
1public class RealService implements IService {
2    @Override
3    public void serve() {
4        System.out.println("真实服务:正在处理请求...");
5    }
6}

3. 创建静态代理类 StaticProxy.java:

复制代码

Java

复制代码
1public class StaticProxy implements IService {
2    private final IService realService;
3
4    public StaticProxy(IService realService) {
5        this.realService = realService;
6    }
7
8    @Override
9    public void serve() {
10        before();
11        realService.serve();
12        after();
13    }
14
15    private void before() {
16        System.out.println("代理开始:记录调用前时间");
17    }
18
19    private void after() {
20        System.out.println("代理结束:记录调用后时间");
21    }
22}

4. 客户端代码:

复制代码

Java

复制代码
1public class Client {
2    public static void main(String[] args) {
3        IService service = new RealService();
4        IService proxyService = new StaticProxy(service);
5        proxyService.serve();
6    }
7}

在这个例子中,StaticProxy作为RealService的静态代理,提供了额外的日志记录功能,而无需修改RealService的代码。

动态代理实例

使用JDK动态代理来实现上述相同的需求,动态代理不需要我们手动创建代理类,而是通过反射机制在运行时动态生成。

1. 保持上面的 IServiceRealService 不变。

2. 动态代理实现 DynamicProxy.java:

复制代码

Java

复制代码
1import java.lang.reflect.InvocationHandler;
2import java.lang.reflect.Method;
3import java.lang.reflect.Proxy;
4
5public class DynamicProxy implements InvocationHandler {
6    private final Object target;
7
8    public DynamicProxy(Object target) {
9        this.target = target;
10    }
11
12    public Object getProxyInstance() {
13        return Proxy.newProxyInstance(
14                target.getClass().getClassLoader(),
15                target.getClass().getInterfaces(),
16                this);
17    }
18
19    @Override
20    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
21        before();
22        Object result = method.invoke(target, args);
23        after();
24        return result;
25    }
26
27    private void before() {
28        System.out.println("动态代理开始:记录调用前时间");
29    }
30
31    private void after() {
32        System.out.println("动态代理结束:记录调用后时间");
33    }
34}

3. 客户端代码调整为使用动态代理:

复制代码

Java

复制代码
1public class Client {
2    public static void main(String[] args) {
3        IService realService = new RealService();
4        IService proxyService = (IService) new DynamicProxy(realService).getProxyInstance();
5        proxyService.serve();
6    }
7}

在这个动态代理的例子中,我们通过InvocationHandler接口的invoke方法来实现在调用前后增加额外功能,而代理类是由Java运行时动态生成的。这种方式更加灵活,特别是当需要为多个实现同一接口的类创建代理时,避免了为每一个类都手动编写静态代理类的繁琐工作。

相关推荐
rit843249944 分钟前
基于MATLAB的模糊图像复原
开发语言·matlab
fie88891 小时前
基于MATLAB的声呐图像特征提取与显示
开发语言·人工智能
程序员小凯1 小时前
Spring Boot测试框架详解
java·spring boot·后端
豐儀麟阁贵1 小时前
基本数据类型
java·算法
_extraordinary_2 小时前
Java SpringMVC(二) --- 响应,综合性练习
java·开发语言
程序员 Harry2 小时前
深度解析:使用ZIP流式读取大型PPTX文件的最佳实践
java
@。1243 小时前
对于灰度发布(金丝雀发布)的了解
开发语言·前端
wxweven3 小时前
校招面试官揭秘:我们到底在寻找什么样的技术人才?
java·面试·校招
陈陈爱java3 小时前
新知识点背诵
java
失散133 小时前
分布式专题——39 RocketMQ客户端编程模型
java·分布式·架构·rocketmq