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运行时动态生成的。这种方式更加灵活,特别是当需要为多个实现同一接口的类创建代理时,避免了为每一个类都手动编写静态代理类的繁琐工作。

相关推荐
代码讲故事17 分钟前
多种方法实现golang中实现对http的响应内容生成图片
开发语言·chrome·http·golang·图片·快照·截图
N_NAN_N24 分钟前
类图+案例+代码详解:软件设计模式----原型模式
java·设计模式·原型模式
佛祖保佑永不宕机28 分钟前
maven引入本地jar包
java·maven·jar
默默coding的程序猿1 小时前
3.前端和后端参数不一致,后端接不到数据的解决方案
java·前端·spring·ssm·springboot·idea·springcloud
虾球xz1 小时前
CppCon 2018 学习:EFFECTIVE REPLACEMENT OF DYNAMIC POLYMORPHISM WITH std::variant
开发语言·c++·学习
Allen_LVyingbo1 小时前
Python常用医疗AI库以及案例解析(2025年版、上)
开发语言·人工智能·python·学习·健康医疗
小哈龙1 小时前
裸仓库 + Git Bash 搭建 本地 Git 服务端与客户端
开发语言·git·bash
在未来等你1 小时前
JVM调优实战 Day 15:云原生环境下的JVM配置
java·jvm·性能优化·虚拟机·调优
funnycoffee1231 小时前
Huawei 6730 Switch software upgrade example版本升级
java·前端·华为
Java初学者小白1 小时前
秋招Day15 - Redis - 缓存设计
java·数据库·redis·缓存