1. 什么是代理模式
代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介作用。
2. 代理模式的核心概念
2.1 主要角色
- Subject(抽象主题):定义了真实主题和代理主题的共同接口
- RealSubject(真实主题):实现了抽象主题接口的具体类
- Proxy(代理):持有真实主题的引用,实现抽象主题接口
2.2 工作原理
Client -> Proxy -> RealSubject
3. Java中代理模式的实现方式
3.1 静态代理
静态代理在编译时就确定了代理关系。
// 抽象主题接口
interface UserService {
void login(String username, String password);
void logout(String username);
}
// 真实主题
class UserServiceImpl implements UserService {
@Override
public void login(String username, String password) {
System.out.println("用户 " + username + " 登录成功");
}
@Override
public void logout(String username) {
System.out.println("用户 " + username + " 退出登录");
}
}
// 静态代理类
class UserServiceProxy implements UserService {
private UserService userService;
public UserServiceProxy(UserService userService) {
this.userService = userService;
}
@Override
public void login(String username, String password) {
// 前置处理
System.out.println("记录登录日志:" + username);
long startTime = System.currentTimeMillis();
// 调用真实对象
userService.login(username, password);
// 后置处理
long endTime = System.currentTimeMillis();
System.out.println("登录耗时:" + (endTime - startTime) + "ms");
}
@Override
public void logout(String username) {
System.out.println("记录退出日志:" + username);
userService.logout(username);
}
}
3.2 JDK动态代理
JDK动态代理基于接口实现,使用反射机制在运行时创建代理对象。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// InvocationHandler实现类
class DynamicProxyHandler implements InvocationHandler {
private Object target;
public DynamicProxyHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置处理
System.out.println("执行方法前:" + method.getName());
long startTime = System.currentTimeMillis();
// 执行目标方法
Object result = method.invoke(target, args);
// 后置处理
long endTime = System.currentTimeMillis();
System.out.println("执行方法后:" + method.getName() + ",耗时:" + (endTime - startTime) + "ms");
return result;
}
}
// 代理工厂
class ProxyFactory {
public static Object createProxy(Object target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new DynamicProxyHandler(target)
);
}
}
// 使用示例
public class DynamicProxyDemo {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserService proxy = (UserService) ProxyFactory.createProxy(userService);
proxy.login("张三", "123456");
proxy.logout("张三");
}
}
3.3 CGLIB动态代理
CGLIB可以为没有接口的类创建代理,通过继承目标类实现。
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
// 目标类(无需实现接口)
class OrderService {
public void createOrder(String orderId) {
System.out.println("创建订单:" + orderId);
}
public void cancelOrder(String orderId) {
System.out.println("取消订单:" + orderId);
}
}
// CGLIB方法拦截器
class CglibMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("CGLIB代理前置处理:" + method.getName());
// 调用父类方法
Object result = proxy.invokeSuper(obj, args);
System.out.println("CGLIB代理后置处理:" + method.getName());
return result;
}
}
// CGLIB代理工厂
class CglibProxyFactory {
public static Object createProxy(Class<?> clazz) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(new CglibMethodInterceptor());
return enhancer.create();
}
}
// 使用示例
public class CglibProxyDemo {
public static void main(String[] args) {
OrderService proxy = (OrderService) CglibProxyFactory.createProxy(OrderService.class);
proxy.createOrder("ORDER001");
proxy.cancelOrder("ORDER001");
}
}
4. 代理模式的应用场景
4.1 远程代理
// 模拟远程服务调用
class RemoteServiceProxy implements UserService {
private String serverUrl;
public RemoteServiceProxy(String serverUrl) {
this.serverUrl = serverUrl;
}
@Override
public void login(String username, String password) {
System.out.println("连接远程服务器:" + serverUrl);
// 模拟网络调用
try {
Thread.sleep(100);
System.out.println("远程登录成功:" + username);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void logout(String username) {
System.out.println("远程退出登录:" + username);
}
}
4.2 缓存代理
import java.util.HashMap;
import java.util.Map;
class CacheProxy implements UserService {
private UserService userService;
private Map<String, Object> cache = new HashMap<>();
public CacheProxy(UserService userService) {
this.userService = userService;
}
@Override
public void login(String username, String password) {
String key = "login_" + username;
if (cache.containsKey(key)) {
System.out.println("从缓存获取登录信息:" + username);
return;
}
userService.login(username, password);
cache.put(key, "logged_in");
System.out.println("登录信息已缓存");
}
@Override
public void logout(String username) {
String key = "login_" + username;
cache.remove(key);
userService.logout(username);
System.out.println("清除缓存:" + username);
}
}

被折叠的 条评论
为什么被折叠?



