代理模式

代理模式的目的是提供一个代理对象来控制对另一个对象的访问。该模式适用于需要控制对象的访问权限、保护对象等场景,如网络代理、远程代理等。

在Java中实现代理模式,通常是通过动态代理或静态代理来实现

静态代理

静态代理是最简单的一种方式,它通过创建一个代理类来实现。这个代理类持有对实际对象的引用,并在其方法调用前后添加额外的操作。

静态代理示例:

假设我们有一个Service接口和它的实现类RealService,我们想要通过一个代理类ServiceProxy来控制对RealService的访问

// Service 接口
public interface Service {
    void performService();
}

// RealService 实现类
public class RealService implements Service {
    @Override
    public void performService() {
        System.out.println("Executing real service");
    }
}

// ServiceProxy 代理类
public class ServiceProxy implements Service {
    private Service realService;

    public ServiceProxy(Service realService) {
        this.realService = realService;
    }

    @Override
    public void performService() {
        preRequest(); // 在实际方法调用前执行
        realService.performService(); // 调用实际的服务方法
        postRequest(); // 在实际方法调用后执行
    }

    private void preRequest() {
        System.out.println("Before service");
    }

    private void postRequest() {
        System.out.println("After service");
    }
}

使用代理

public class Main {
    public static void main(String[] args) {
        Service realService = new RealService();
        Service proxy = new ServiceProxy(realService);
        proxy.performService(); // 输出将会显示代理的逻辑执行前后信息。
    }
}

** 动态代理**

动态代理允许在运行时动态地创建代理类和对象,而不需要事先为每个服务接口编写代理类。这在接口很多或者接口经常变化时非常有用。

动态代理示例

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.*; // 注意:通常不需要导入两次java.lang.reflect包。这里为了示例清晰,重复了一次。实际使用时只需导入一次。
import java.util.*; // 通常不需要导入这些,只是为了完整性示例中包括了这些导入。根据实际需要选择是否需要这些导入。

// 实现InvocationHandler接口来创建自己的调用处理器
public class DynamicProxyHandler implements InvocationHandler {
    private Object target; // 被代理的真实对象,可以是任何类型的对象,只要实现了目标接口即可。

    public DynamicProxyHandler(Object target) { // 构造函数,传入真实对象。
        this.target = target; // 将真实对象赋值给target变量。这样在invoke方法中就可以通过target来调用真实对象的方法了。
    }
    @Override // 重写invoke方法,以实现自定义的代理逻辑。invoke方法会在每次调用代理对象的方法时被自动调用。其参数分别是:代理对象、方法、参数列表。返回值是方法调用的结果。如果方法抛出异常,则invoke方法也应该抛出异常。这里需要注意的是,invoke方法的第一个参数是代理对象本身,第二个参数是当前正在被调用的方法对象,第三个参数是调用该方法时所传递的参数列表(如果有的话)。如果该方法没有参数,则第三个参数会是null。最后一个参数是方法的原始类型(即该方法所属的类)。在invoke方法中,我们可以根据需要对这些参数进行处理,然后调用真实对象的方法(即this.target),并将结果返回给调用者。如果需要改变方法的返回值或抛出异常,也可以在这里实现。例如,可以在调用真实对象的方法前后添加日志记录、性能统计等操作。如果需要改变方法的返回值或抛出异常,也可以在这里实现。例如,可以在调用真实对象的方法前后添加日志记录、性能统计等操作。如果要改变方法的返回值或抛出异常,也可以在invoke方法中实现这些逻辑。例如,可以在调用真实对象的方法前后添加日志记录、性能统计等操作。如果要改变方法的返回值或抛出异常,也可以在invoke方法中实现这些逻辑。例如,可以在调用真实对象的方法前后添加日志记录、性能统计等操作。如果要改变方法的返回值或抛