简介
在 Java 中,代理(Proxy)模式是一种设计模式,它允许你为对象提供一个替身或占位符,以控制对该对象的访问。代理模式可以用于各种场景,比如延迟加载、访问控制、日志记录、事务处理等。
Java 中有两种常见的代理方式:
静态代理
静态代理类在编译期间就已经确定,需要手动编写代理类,通常,静态代理类实现与被代理对象相同的接口,并且在代理类中可以对方法的调用进行增强处理。
在下面的例子中,ServiceProxy 是 RealService 的代理,它在调用 performAction 方法之前和之后做了一些额外的工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public interface Service { void performAction(); }
public class RealService implements Service { @Override public void performAction() { System.out.println("Performing action in RealService"); } }
public class ServiceProxy implements Service { private Service realService;
public ServiceProxy(Service realService) { this.realService = realService; }
@Override public void performAction() { System.out.println("Proxy before action"); realService.performAction(); System.out.println("Proxy after action"); } }
public class Main { public static void main(String[] args) { Service service = new ServiceProxy(new RealService()); service.performAction(); } }
|
动态代理
Java 的动态代理是在运行时生成代理类。Java 提供了两种动态代理的方式:
- JDK 动态代理:用于代理实现了接口的类。
- CGLIB 动态代理:用于代理没有实现接口的类。
JDK 动态代理
JDK 动态代理依赖于 java.lang.reflect.Proxy 类和 InvocationHandler 接口。
在这个示例中,Proxy.newProxyInstance 方法用于动态创建一个代理对象。通过 InvocationHandler 接口的 invoke 方法,可以在调用真实对象的方法之前或之后执行一些额外操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;
public interface Service { void performAction(); }
public class RealService implements Service{ @Override public void performAction() { System.out.println("Performing action in RealService"); } }
public class ServiceInvocationHandler implements InvocationHandler { private Object target;
public ServiceInvocationHandler(Object target) { this.target = target; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Proxy before action"); Object result = method.invoke(target, args); System.out.println("Proxy after action"); return result; } }
public class Main { public static void main(String[] args) { Service realService = new RealService(); Service proxyService = (Service) Proxy.newProxyInstance( realService.getClass().getClassLoader(), new Class[]{Service.class}, new ServiceInvocationHandler(realService) ); proxyService.performAction(); } }
|
CGLIB 动态代理
CGLIB 动态代理不要求目标类实现接口,它通过继承目标类来创建代理对象。CGLIB 常用于没有实现接口的类的代理。
需要注意,JDK 动态代理只能代理实现了接口的类,而 CGLIB 可以代理没有接口的类。