【设计模式】代理模式(结构型)⭐⭐⭐

作者 : admin 本文共3354个字,预计阅读时间需要9分钟 发布时间: 2024-06-9 共3人阅读

文章目录

  • 1.概念
  • 2.实现方式
    • 2.1 静态代理
    • 2.2 动态代理
  • 3. Java 哪些地方用到了代理模式
  • 4. Spring 哪些地方用到了代理模式

1.概念

1.1 什么是代理模式

代理模式(Proxy Pattern)是一种结构型设计模式,它允许通过一个代理对象来控制对另一个对象的访问。

1.2 优点与缺点

优点:
1.可以控制对真实对象的访问。
2.可以延迟真实对象的创建,减少系统开销。
3.可以提供额外的服务,如缓存、权限检查等。
缺点:
1.增加了系统的复杂性,因为引入了额外的代理类。
2.可能会降低系统的性能,因为代理会增加一层间接调用。

2.实现方式

2.1 静态代理

// Image接口
public interface Image {
    void display();
}

// RealImage类,实现了Image接口
public class RealImage implements Image {
    private String fileName;

    // 构造函数,加载图像
    public RealImage(String fileName) {
        this.fileName = fileName;
        loadImageFromDisk();
    }

    // 加载图像的模拟方法
    private void loadImageFromDisk() {
        System.out.println("Loading  " + fileName);
    }

    // 显示图像
    @Override
    public void display() {
        System.out.println("Displaying " + fileName);
    }
}

// Image代理类
public class ImageProxy implements Image {
    private String fileName;
    private Image realImage;

    // 构造函数
    public ImageProxy(String fileName) {
        this.fileName = fileName;
    }

    // 显示图像,如果真实图像尚未加载,则先加载
    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(fileName);
        }
        realImage.display();
    }
}

// 测试类
public class ProxyPatternDemo {
    public static void main(String[] args) {
        Image image = new ImageProxy("test_10mb.jpg");

        // 图像将从磁盘加载
        image.display();
        System.out.println("");

        // 图像不需要从磁盘加载
        image.display();
    }
}

2.2 动态代理

动态代理通常使用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口来实现。

// Image接口
public interface Image {
void display();
}
// RealImage类,实现了Image接口
public class RealImage implements Image {
private String fileName;
// 构造函数,加载图像
public RealImage(String fileName) {
this.fileName = fileName;
loadImageFromDisk();
}
// 加载图像的模拟方法
private void loadImageFromDisk() {
System.out.println("Loading  " + fileName);
}
// 显示图像
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
}
// 动态代理类
public class DynamicImageProxy {
public static Image newInstance(String fileName) {
return (Image) java.lang.reflect.Proxy.newProxyInstance(
Image.class.getClassLoader(),
new Class[]{Image.class},
new java.lang.reflect.InvocationHandler() {
private Image realImage = null;
@Override
public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable {
if (realImage == null) {
realImage = new RealImage(fileName);
}
return method.invoke(realImage, args);
}
}
);
}
}
// 测试类
public class ProxyPatternDemo {
public static void main(String[] args) {
Image image = DynamicImageProxy.newInstance("test_10mb.jpg");
// 图像将从磁盘加载
image.display();
System.out.println("");
// 图像不需要从磁盘加载
image.display();
}
}

3. Java 哪些地方用到了代理模式

RMI(Remote Method Invocation): Java的RMI机制使用代理模式来实现远程对象的透明访问。RMI系统提供的代理类将远程方法调用转换为对远程对象的调用。
JDBC(Java Database Connectivity): JDBC驱动程序管理器使用代理模式来加载和实例化JDBC驱动程序。当应用程序请求连接到数据库时,代理会加载适当的驱动程序并建立连接。
动态代理: Java的动态代理机制允许在运行时创建代理类和代理实例。这通常用于AOP(面向切面编程)框架,如Spring AOP,其中代理用于在目标对象的方法调用前后执行增强代码。
事件监听器: 在Swing或其他GUI框架中,事件监听器使用代理模式来处理事件。事件源将事件委托给事件监听器,后者作为事件处理的代理。
延迟加载: 在Hibernate或其他ORM框架中,代理模式用于实现延迟加载。代理对象代表真实对象,并在真正需要访问对象数据时才加载数据。
保护代理: 在需要控制对资源的访问时,可以使用保护代理来检查调用者的权限,并根据权限决定是否允许访问资源。
智能引用: 在需要跟踪对象的使用情况时,可以使用智能代理来记录对象的使用次数、最后使用时间等信息。

4. Spring 哪些地方用到了代理模式

AOP(面向切面编程): Spring AOP使用代理模式来实现方法拦截。Spring的AopProxy类充当代理,它根据配置创建代理对象,并在目标对象的方法调用前后执行增强代码。
事务管理: Spring的事务管理器使用代理模式来管理事务。TransactionInterceptor类充当代理,它在目标方法执行前后管理事务的开启、提交或回滚。
事件发布: Spring的事件驱动模型使用代理模式来解耦事件的生产者和消费者。ApplicationEventMulticaster类充当代理,它将事件发布给所有注册的监听器。
Web集成: Spring的Web模块使用代理模式来集成不同的Web框架。例如,DispatcherServlet充当代理,它将HTTP请求转换为Spring MVC框架的调用。
资源访问: Spring的ResourceLoader和Resource接口使用代理模式来抽象不同类型的资源访问。ResourceLoader的实现类充当代理,它们将资源访问的调用转换为具体文件系统、类路径或URL的访问。
消息服务: Spring的JMS(Java消息服务)集成使用代理模式来适配不同的消息中间件。JmsTemplate和JmsListenerContainerFactory类充当代理,它们将Spring的消息抽象转换为具体的消息中间件操作。

本站无任何商业行为
个人在线分享 » 【设计模式】代理模式(结构型)⭐⭐⭐
E-->