21xrx.com
2025-03-27 14:01:21 Thursday
文章检索 我的文章 写文章
Java代理模式的使用及实现
2023-06-19 02:25:08 深夜i     10     0
Java 代理模式 静态代理 动态代理

Java代理模式是一种常见的设计模式,它允许那些无法直接访问原始对象的客户端通过代理来访问。代理实际上是对象的替身,通过代理我们可以控制对象的访问和操作。本文将详细介绍Java代理模式的使用及实现。

Java代理模式有两种实现方式:静态代理和动态代理。首先我们看看静态代理。在静态代理中,代理模式需要为每个需要进行代理的类都创建一个代理类,这意味着代码复用性比较差,但是对于一些简单的实现,静态代理是非常有用的。下面是一段示例代码:

public interface Image {
  void display();
}
public class RealImage implements Image {
  private String fileName;
  public RealImage(String fileName){
    this.fileName = fileName;
    loadFromDisk(fileName);
  }
  @Override
  public void display() {
    System.out.println("Displaying " + fileName);
  }
  private void loadFromDisk(String fileName){
    System.out.println("Loading " + fileName);
  }
}
public 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();
  }
}

在上面的代码中,我们定义了一个接口Image,和两个实现类:RealImage和ProxyImage,RealImage是实际需要被运行的类,而ProxyImage则是代理类。

接下来通过一个简单的测试类来运行这些类:

public class ProxyPatternDemo {
  public static void main(String[] args) {
    Image image = new ProxyImage("test.jpg");
    // 图像将从磁盘中加载
    image.display();
    System.out.println("");
    // 图像不需要从磁盘中加载
    image.display();
  }
}

接下来,我们看看动态代理。动态代理是在运行时创建的,它可以动态地为一个类创建代理。动态代理通常使用Java.lang.reflect包中的Proxy类来实现。下面是一个简单的示例:

public interface Subject {
  void rent();
  void hello(String str);
}
public class RealSubject implements Subject {
  @Override
  public void rent() {
    System.out.println("I want to rent my house");
  }
  @Override
  public void hello(String str) {
    System.out.println("hello: " + str);
  }
}
public 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.getName() + " ++++++");
    Object result = method.invoke(target, args);
    System.out.println("++++++after " + method.getName() + " ++++++");
    return result;
  }
}

在上面的示例中,我们定义了一个接口Subject和它的实现类RealSubject。ProxyHandler类是一个实现了InvocationHandler接口的代理处理类,我们可以在这个类中添加我们需要的代理逻辑。

测试一下这个示例:

public class DynamicProxyDemo {
  public static void main(String[] args) {
    RealSubject realSubject = new RealSubject();
    ProxyHandler proxyHandler = new ProxyHandler(realSubject);
    Subject subject = (Subject) Proxy.newProxyInstance(RealSubject.class.getClassLoader(),
        RealSubject.class.getInterfaces(), proxyHandler);
    subject.rent();
    subject.hello("world");
  }
}

通过上述代码我们可以看到,Java代理模式是实现代理类的一种常见方式,它可以用于限制用户对某些类的直接访问,从而增加控制力。而且,在某些情况下,代理类可以使得整个应用程序更加灵活。

  
  

评论区