代理模式是一种设计模式,它允许通过创建一个代理对象来控制对另一个对象的访问。代理模式可以用于实现访问控制、远程访问、延迟加载等功能。
在Java中,代理模式可以通过以下方式实现:
1. 静态代理:
- 创建一个接口(Subject),定义了被代理对象和代理对象的共同行为。
- 创建一个被代理类(RealSubject),实现了接口,并提供了具体的实现逻辑。
- 创建一个代理类(ProxySubject),实现了接口,并在内部持有一个被代理对象的引用。代理类可以在调用被代理对象之前或之后执行额外的逻辑。
- 在客户端中,通过实例化代理类来访问被代理对象。
以下是一个简单的示例代码,演示了如何使用静态代理实现代理模式:
- // 接口
- interface Image {
- void display();
- }
-
- // 被代理类
- class RealImage implements Image {
- private String filename;
-
- public RealImage(String filename) {
- this.filename = filename;
- loadFromDisk();
- }
-
- private void loadFromDisk() {
- System.out.println("Loading image: " + filename);
- }
-
- @Override
- public void display() {
- System.out.println("Displaying image: " + filename);
- }
- }
-
- // 代理类
- class ProxyImage implements Image {
- private RealImage realImage;
- private String filename;
-
- public ProxyImage(String filename) {
- this.filename = filename;
- }
-
- @Override
- public void display() {
- if (realImage == null) {
- realImage = new RealImage(filename);
- }
- realImage.display();
- }
- }
-
- // 客户端
- public class Main {
- public static void main(String[] args) {
- Image image = new ProxyImage("image.jpg");
- // 图像加载和显示由代理类控制
- image.display();
- }
- }
在这个示例中,Image接口定义了被代理对象和代理对象的共同行为。RealImage类是被代理类,实现了Image接口,并提供了具体的实现逻辑。ProxyImage类是代理类,实现了Image接口,并在内部持有一个RealImage对象的引用。在display方法中,代理类可以在调用被代理对象之前或之后执行额外的逻辑。在客户端中,通过实例化代理类来访问被代理对象。
2. 动态代理:
- 创建一个接口(Subject),定义了被代理对象和代理对象的共同行为。
- 创建一个实现了InvocationHandler接口的代理处理器类(ProxyHandler),在invoke方法中实现对被代理对象方法的调用和额外逻辑的处理。
- 使用Java提供的Proxy类的静态方法newProxyInstance来创建代理对象。该方法接受一个类加载器、一组接口和一个代理处理器对象作为参数。
- 在客户端中,通过调用代理对象的方法来访问被代理对象。
以下是一个简单的示例代码,演示了如何使用动态代理实现代理模式:
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
-
- // 接口
- interface Image {
- void display();
- }
-
- // 被代理类
- class RealImage implements Image {
- private String filename;
-
- public RealImage(String filename) {
- this.filename = filename;
- loadFromDisk();
- }
-
- private void loadFromDisk() {
- System.out.println("Loading image: " + filename);
- }
-
- @Override
- public void display() {
- System.out.println("Displaying image: " + filename);
- }
- }
-
- // 代理处理器类
- class ProxyHandler implements InvocationHandler {
- private Object target;
-
- public ProxyHandler(Object target) {
- this.target = target;
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- System.out.println("Before method: " + method.getName());
- Object result = method.invoke(target, args);
- System.out.println("After method: " + method.getName());
- return result;
- }
- }
-
- // 客户端
- public class Main {
- public static void main(String[] args) {
- Image realImage = new RealImage("image.jpg");
-
- // 创建代理对象
- Image proxyImage = (Image) Proxy.newProxyInstance(
- realImage.getClass().getClassLoader(),
- realImage.getClass().getInterfaces(),
- new ProxyHandler(realImage)
- );
-
- // 图像加载和显示由代理对象控制
- proxyImage.display();
- }
- }
在这个示例中,Image接口定义了被代理对象和代理对象的共同行为。RealImage类是被代理类,实现了Image接口,并提供了具体的实现逻辑。ProxyHandler类是代理处理器类,实现了InvocationHandler接口,在invoke方法中实现了对被代理对象方法的调用和额外逻辑的处理。在客户端中,通过调用Proxy类的newProxyInstance方法来创建代理对象,该方法接受一个类加载器、一组接口和一个代理处理器对象作为参数。通过代理对象调用方法时,代理处理器会在方法调用前后执行额外的逻辑。
动态代理模式可以在运行时创建代理对象,使得代理对象的行为可以动态地改变,提供了更大的灵活性和扩展性。