在 Java 中实现代理模式通常包括两种方式:静态代理和动态代理。静态代理是在编译时就已经确定代理类和真实对象的关系,而动态代理则是在运行时动态生成代理类。下面,我会分别解释如何在项目中实践这两种代理模式。
静态代理
- 定义接口:首先定义一个接口,声明你想要代理的方法。
1public interface IService {
2 void serve();
3}
- 实现接口:创建一个真实对象类,实现上述接口。
1public class RealService implements IService {
2 @Override
3 public void serve() {
4 System.out.println("Serving something important...");
5 }
6}
- 创建代理类:然后创建一个代理类,同样实现这个接口,并在内部持有一个真实对象的引用,代理类可以在调用真实对象的方法前后添加额外的逻辑。
1 public class ProxyService implements IService {
2 private IService realService;
3
4 public ProxyService(IService realService) {
5 this.realService = realService;
6 }
7
8 @Override
9 public void serve() {
10 System.out.println("Proxy before serving...");
11 realService.serve();
12 System.out.println("Proxy after serving...");
13 }
14}
- 使用代理:在客户端代码中,使用代理类来替代真实对象。
1 public class Client {
2 public static void main(String[] args) {
3 IService realService = new RealService();
4 IService proxyService = new ProxyService(realService);
5
6 proxyService.serve();
7 }
8}
动态代理
在Java中,动态代理通常是通过java.lang.reflect.Proxy类和
java.lang.reflect.InvocationHandler接口来实现的。
- 定义接口:这一步和静态代理相同,你需要一个接口。
1public interface IService {
2 void serve();
3}
- 实现接口:创建真实对象类,实现接口。
1public class RealService implements IService {
2 @Override
3 public void serve() {
4 System.out.println("Serving something important...");
5 }
6}
- 创建调用处理器:创建一个InvocationHandler,它定义了代理实例的调用处理程序。
1public class ProxyInvocationHandler implements InvocationHandler {
2 private Object target;
3
4 public ProxyInvocationHandler(Object target) {
5 this.target = target;
6 }
7
8 @Override
9 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
10 System.out.println("Invoking method: " + method.getName());
11 Object result = method.invoke(target, args);
12 System.out.println("Method executed: " + method.getName());
13 return result;
14 }
15}
- 使用动态代理:在客户端代码中,创建真实对象的代理实例,并通过它调用方法。
1public class Client {
2 public static void main(String[] args) {
3 IService realService = new RealService();
4 IService proxyService = (IService) Proxy.newProxyInstance(
5 realService.getClass().getClassLoader(),
6 new Class[] { IService.class },
7 new ProxyInvocationHandler(realService)
8 );
9
10 proxyService.serve();
11 }
12}
在上面的动态代理例子中,Proxy.newProxyInstance方法创建了一个实现了IService接口的代理实例,所有对该代理实例的方法调用都会被转发到
ProxyInvocationHandler.invoke方法。
这些是代理模式在Java项目中的基本实践。在实际的项目中,代理模式常常用于访问控制、懒加载、日志记录、性能计数、事务处理等场景。