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

相关推荐
x***133921 小时前
MySQL 篇 - Java 连接 MySQL 数据库并实现数据交互
java·数据库·mysql
xuanzdhc21 小时前
Gitgit
java·linux·运维·服务器·c++·git
自学互联网21 小时前
使用Python构建钢铁行业生产监控系统:从理论到实践
开发语言·python
合作小小程序员小小店21 小时前
桌面开发,在线%医院管理%系统,基于vs2022,c#,winform,sql server数据
开发语言·数据库·sql·microsoft·c#
无心水21 小时前
【Python实战进阶】7、Python条件与循环实战详解:从基础语法到高级技巧
android·java·python·python列表推导式·python条件语句·python循环语句·python实战案例
一点★21 小时前
“equals”与“==”、“hashCode”的区别和使用场景
java·开发语言
N***H48621 小时前
SpringCloud实战十三:Gateway之 Spring Cloud Gateway 动态路由
java·spring cloud·gateway
十一.36621 小时前
79-82 call和apply,arguments,Date对象,Math
开发语言·前端·javascript
合作小小程序员小小店21 小时前
桌面开发,下午茶甜品管理系统开发,基于C#,winform,sql server数据库
开发语言·数据库·sql·microsoft·c#
s***w1121 天前
SpringMVC新版本踩坑[已解决]
java