什么是代理模式?
代理模式(Proxy Pattern)是一种结构型设计模式,它允许你提供一个代理来控制对其他对象的访问。代理对象可以在客户端和目标对象之间起到中介的作用,并且可以添加额外的功能。
为什么使用代理模式?
- 控制对对象的访问
- 在访问对象时添加额外的功能
- 延迟加载
- 权限控制
代理模式的类型
- 静态代理
- 动态代理(JDK动态代理)
- CGLIB代理
实现示例
1. 静态代理
// 共同的接口
public interface Subject {
void request();
}
// 真实主题
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject处理请求");
}
}
// 代理类
public class Proxy implements Subject {
private RealSubject realSubject;
public Proxy() {
this.realSubject = new RealSubject();
}
@Override
public void request() {
System.out.println("代理开始");
realSubject.request();
System.out.println("代理结束");
}
}2. JDK动态代理
// 接口
public interface UserService {
void addUser(String userId, String userName);
void deleteUser(String userId);
}
// 实现类
public class UserServiceImpl implements UserService {
@Override
public void addUser(String userId, String userName) {
System.out.println("添加用户: " + userName);
}
@Override
public void deleteUser(String userId) {
System.out.println("删除用户: " + userId);
}
}
// 动态代理处理器
public class LogHandler implements InvocationHandler {
private Object target;
public LogHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始执行方法: " + method.getName());
Object result = method.invoke(target, args);
System.out.println("方法执行结束");
return result;
}
public static Object createProxy(Object target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new LogHandler(target)
);
}
}3. CGLIB代理
// 目标类
public class UserDao {
public void save(User user) {
System.out.println("保存用户: " + user.getName());
}
public void delete(String userId) {
System.out.println("删除用户: " + userId);
}
}
// CGLIB代理
public class CglibProxy implements MethodInterceptor {
private Object target;
public CglibProxy(Object target) {
this.target = target;
}
public Object getProxyInstance() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
throws Throwable {
System.out.println("开始执行方法: " + method.getName());
Object result = proxy.invokeSuper(obj, args);
System.out.println("方法执行结束");
return result;
}
}4. 实际应用示例:远程代理
// 远程服务接口
public interface RemoteService {
String getData(String key);
}
// 远程服务实现
public class RemoteServiceImpl implements RemoteService {
@Override
public String getData(String key) {
// 模拟远程调用
return "Data for key: " + key;
}
}
// 远程代理
public class RemoteProxy implements RemoteService {
private RemoteService remoteService;
public RemoteProxy() {
// 模拟RPC获取远程服务实例
this.remoteService = new RemoteServiceImpl();
}
@Override
public String getData(String key) {
try {
System.out.println("准备远程调用");
String result = remoteService.getData(key);
System.out.println("远程调用成功");
return result;
} catch (Exception e) {
System.out.println("远程调用失败: " + e.getMessage());
return null;
}
}
}5. 使用示例
public class Client {
public static void main(String[] args) {
// 静态代理
Subject proxy = new Proxy();
proxy.request();
// JDK动态代理
UserService userService = new UserServiceImpl();
UserService proxyService = (UserService) LogHandler.createProxy(userService);
proxyService.addUser("1", "张三");
// CGLIB代理
UserDao userDao = new UserDao();
UserDao proxyDao = (UserDao) new CglibProxy(userDao).getProxyInstance();
proxyDao.save(new User("李四"));
// 远程代理
RemoteService remoteProxy = new RemoteProxy();
String data = remoteProxy.getData("test");
System.out.println(data);
}
}代理模式的优点
- 职责清晰
- 高扩展性
- 智能化
- 保护目标对象
代理模式的缺点
- 在客户端和目标对象之间增加代理对象,可能会降低系统性能
- 实现代理模式需要额外的工作
- 有些代理模式的实现非常复杂
适用场景
- 远程代理:为远程对象提供代理
- 虚拟代理:延迟加载
- 保护代理:控制对对象的访问
- 智能引用:在访问对象时添加额外的操作
与其他模式的关系
- 装饰器模式:装饰器为对象添加功能,代理控制对对象的访问
- 适配器模式:适配器提供不同接口,代理提供相同接口
- 外观模式:外观模式简化接口,代理模式控制访问
总结
代理模式是一种非常实用的设计模式,它可以在不修改原有代码的情况下,通过代理对象来控制对目标对象的访问。Java中提供了多种代理实现方式,包括静态代理、JDK动态代理和CGLIB代理,可以根据具体需求选择合适的实现方式。
参考资料
- 《Design Patterns: Elements of Reusable Object-Oriented Software》
- 《Head First Design Patterns》
- Spring AOP 文档
- Java动态代理机制分析

