代理模式(Proxy Pattern)是一种结构型设计模式,它通过为目标对象提供一个代理对象来控制对其的访问。代理对象可以在客户端和目标对象之间充当中介,添加额外的功能,如权限控制、延迟加载等。本文将介绍代理模式的定义、实现方式及其在 Java 中的应用。
代理模式的核心思想是:通过代理对象间接访问目标对象,从而在访问前后添加额外逻辑(如日志、权限校验)或控制访问行为(如懒加载)。它适用于需要保护、增强或优化目标对象访问的场景。
Proxy
类)。以下是一个示例:模拟一个文件访问系统,通过代理控制用户对文件的访问权限。
public interface FileAccess {
void readFile(String fileName);
}
public class RealFileAccess implements FileAccess {
@Override
public void readFile(String fileName) {
System.out.println("读取文件: " + fileName);
}
}
public class FileAccessProxy implements FileAccess {
private RealFileAccess realFileAccess;
private String userRole;
public FileAccessProxy(String userRole) {
this.userRole = userRole;
this.realFileAccess = new RealFileAccess();
}
@Override
public void readFile(String fileName) {
// 权限校验
if ("admin".equals(userRole)) {
realFileAccess.readFile(fileName);
} else {
System.out.println("权限不足,无法读取文件: " + fileName);
}
}
}
public class Client {
public static void main(String[] args) {
// 管理员用户
FileAccess adminAccess = new FileAccessProxy("admin");
adminAccess.readFile("data.txt");
// 普通用户
FileAccess userAccess = new FileAccessProxy("user");
userAccess.readFile("data.txt");
}
}
读取文件: data.txt
权限不足,无法读取文件: data.txt
Java 提供了 java.lang.reflect.Proxy
类支持动态代理。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicFileAccessProxy implements InvocationHandler {
private RealFileAccess realFileAccess;
private String userRole;
public DynamicFileAccessProxy(RealFileAccess realFileAccess, String userRole) {
this.realFileAccess = realFileAccess;
this.userRole = userRole;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("readFile".equals(method.getName()) && !"admin".equals(userRole)) {
System.out.println("权限不足,无法读取文件: " + args[0]);
return null;
}
return method.invoke(realFileAccess, args);
}
public static FileAccess createProxy(RealFileAccess realFileAccess, String userRole) {
return (FileAccess) Proxy.newProxyInstance(
realFileAccess.getClass().getClassLoader(),
new Class[]{FileAccess.class},
new DynamicFileAccessProxy(realFileAccess, userRole)
);
}
}
public class Client {
public static void main(String[] args) {
RealFileAccess realFileAccess = new RealFileAccess();
// 管理员用户
FileAccess adminProxy = DynamicFileAccessProxy.createProxy(realFileAccess, "admin");
adminProxy.readFile("data.txt");
// 普通用户
FileAccess userProxy = DynamicFileAccessProxy.createProxy(realFileAccess, "user");
userProxy.readFile("data.txt");
}
}
同静态代理。
@Aspect
@Component
public class LogAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore() {
System.out.println("方法执行前记录日志");
}
}
Spring 使用动态代理为目标方法添加日志逻辑。
代理模式通过为目标对象提供中介,实现了访问控制和功能增强的优雅方案。静态代理实现简单,适合固定场景;动态代理灵活通用,广泛应用于框架设计。在 Java 中,代理模式是 Spring、Hibernate 等框架的核心机制之一。掌握这一模式,能有效提升系统的安全性、可维护性和扩展性。
希望这篇博文能帮助你理解代理模式的精髓!如果有其他设计模式相关问题,欢迎留言讨论。