以下是 代理模式 (Proxy Pattern) 的详细介绍,包含定义、优缺点、应用场景及代码实现:
以下通过 图片加载系统 的案例演示代理模式,包含静态代理和动态代理两种实现:
/**
* 抽象主题接口:定义图片加载行为
*/
public interface Image {
void display();
}
/**
* 真实主题类:实现图片加载逻辑
*/
public class RealImage implements Image {
private final String filename;
public RealImage(String filename) {
this.filename = filename;
loadFromDisk(); // 初始化时直接加载图片
}
private void loadFromDisk() {
System.out.println("从磁盘加载图片: " + filename);
}
@Override
public void display() {
System.out.println("显示图片: " + filename);
}
}
/**
* 静态代理类:延迟加载图片(仅在 display() 时加载)
*/
public class ProxyImage implements Image {
private RealImage realImage; // 持有真实对象的引用
private final String filename;
public ProxyImage(String filename) {
this.filename = filename;
}
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage(filename); // 延迟初始化
}
realImage.display();
}
}
public class Client {
public static void main(String[] args) {
// 使用代理对象(此时未加载图片)
Image image = new ProxyImage("test.jpg");
// 调用 display() 时才真正加载图片
image.display();
}
}
从磁盘加载图片: test.jpg
显示图片: test.jpg
/**
* 抽象主题接口:用户服务
*/
public interface UserService {
void addUser(String name);
void deleteUser(String name);
}
/**
* 真实主题类:用户服务实现
*/
public class UserServiceImpl implements UserService {
@Override
public void addUser(String name) {
System.out.println("添加用户: " + name);
}
@Override
public void deleteUser(String name) {
System.out.println("删除用户: " + name);
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 动态代理处理器:为所有方法添加日志
*/
public class LogInvocationHandler implements InvocationHandler {
private final Object target; // 被代理的真实对象
public LogInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置增强:记录方法名和参数
System.out.println("[日志] 调用方法: " + method.getName() + ", 参数: " + args[0]);
// 调用真实对象的方法
Object result = method.invoke(target, args);
// 后置增强(此处省略)
return result;
}
}
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
// 创建真实对象
UserService realService = new UserServiceImpl();
// 创建动态代理对象
UserService proxyService = (UserService) Proxy.newProxyInstance(
realService.getClass().getClassLoader(),
realService.getClass().getInterfaces(),
new LogInvocationHandler(realService)
);
// 通过代理对象调用方法
proxyService.addUser("Alice");
proxyService.deleteUser("Bob");
}
}
[日志] 调用方法: addUser, 参数: Alice
添加用户: Alice
[日志] 调用方法: deleteUser, 参数: Bob
删除用户: Bob
+----------------+ +----------------+
| Subject | <------+ | Proxy |
+----------------+ +----------------+
| +request() | | -realSubject:Subject|
+----------------+ | +request() |
^ +----------------+
| ^
| |
+----------------+ +----------------+
| RealSubject | | |
+----------------+ +----------------+
| +request() | | |
+----------------+ +----------------+
Enhancer
)。
代理模式在 Java 生态中广泛应用,例如:
掌握代理模式能显著提升系统架构的灵活性和可维护性。