Java设计模式之代理模式

代理模式是 Java 中常用的设计模式之一,它通过引入一个代理对象来控制对实际对象的访问,从而实现对目标对象的间接访问和控制。代理模式可以用于多种场景,比如权限控制、延迟加载、日志记录等。

在 Java 中,代理模式通常分为静态代理和动态代理两种实现方式。下面分别介绍这两种代理模式的实现。

  1. 静态代理

静态代理是在编译时就已经确定代理类和目标类的关系,代理类是手动编写的。静态代理需要为每一个需要代理的类编写一个代理类,这样会导致代码冗余。以下是静态代理的一个简单示例:

```java

// 定义接口

public interface Image {

void display();

}

// 目标类

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 ImageProxy implements Image {

private RealImage realImage;

private String filename;

public ImageProxy(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 ImageProxy("test.jpg");

// 图片加载和显示都由代理类处理

image.display();

}

}

```

  1. 动态代理

动态代理是在运行时动态生成代理类,无需手动编写代理类。Java 中的动态代理主要基于两个类:`java.lang.reflect.Proxy` 和 `java.lang.reflect.InvocationHandler`。以下是动态代理的一个简单示例:

```java

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;

loadImageFromDisk();

}

private void loadImageFromDisk() {

System.out.println("Loading " + filename);

}

@Override

public void display() {

System.out.println("Displaying " + filename);

}

}

// InvocationHandler 实现类

class ImageInvocationHandler implements InvocationHandler {

private Object target;

public ImageInvocationHandler(Object target) {

this.target = target;

}

@Override

public Object invoke(Object proxy, Method method, Object\[\] args) throws Throwable {

System.out.println("Before method execution");

Object result = method.invoke(target, args);

System.out.println("After method execution");

return result;

}

}

// 使用示例

public class Main {

public static void main(String\[\] args) {

Image realImage = new RealImage("test.jpg");

Image proxyImage = (Image) Proxy.newProxyInstance(

Image.class.getClassLoader(),

new Class\[\]{Image.class},

new ImageInvocationHandler(realImage)

);

// 图片加载和显示由代理类处理,并且在方法执行前后添加了额外逻辑

proxyImage.display();

}

}

无论是静态代理还是动态代理,都能够实现对目标对象的代理和控制,根据具体的需求选择合适的代理模式。动态代理相比静态代理更加灵活,但是也需要理解其背后的原理和实现机制。

相关推荐
Suxing99 小时前
C语言基础分享:从“租房”到“拆迁”,C语言动态内存管理
java·数据结构·算法
减瓦9 小时前
别让 Java 版本选择变成生产事故
java
ikun_文9 小时前
Java集合框架Collection拓展进阶
java·java ee
码匠许师傅9 小时前
【C++ 面试真题】聊聊 C++ 的虚函数和多态
java·c++·面试
chuan.bai9 小时前
Java RAG 实战(第 8 篇):Spring Boot RAG 查询 API
java·spring boot·贪心算法
FlyWIHTSKY9 小时前
idea中集成claude功能
java·ide·人工智能·intellij-idea·cloudera
Java成神之路-9 小时前
Spring AI 统一结构化返回:ChatModel / ChatClient 两种实现方式
java·springaialibaba
Mr. zhihao9 小时前
深度解析:为什么Java序列化需要搭配ByteArrayOutputStream?IO装饰器模式的精妙设计
java·开发语言·装饰器模式
存在morning10 小时前
【Python 开发实践 一】Python vs Go vs Java 三门语言对比
java·python·golang
vx-程序开发10 小时前
springboot旅游推介平台---附源码24175
java·spring boot·python·spring cloud·eclipse·django·idea