静态代理实例
假设我们有一个需求,要记录一个服务接口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. 保持上面的 IService
和 RealService
不变。
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运行时动态生成的。这种方式更加灵活,特别是当需要为多个实现同一接口的类创建代理时,避免了为每一个类都手动编写静态代理类的繁琐工作。