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

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的消息抽象转换为具体的消息中间件操作。

  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leo❀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值