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

相关推荐
百事老饼干4 分钟前
Java[面试题]-真实面试
java·开发语言·面试
customer0812 分钟前
【开源免费】基于SpringBoot+Vue.JS医院管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·开源·intellij-idea
2402_8575893622 分钟前
SpringBoot框架:作业管理技术新解
java·spring boot·后端
HBryce2425 分钟前
缓存-基础概念
java·缓存
一只爱打拳的程序猿40 分钟前
【Spring】更加简单的将对象存入Spring中并使用
java·后端·spring
杨荧41 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
minDuck43 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
白子寰1 小时前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
王俊山IT1 小时前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习