本文目录导读:

我将为您详细介绍Java代理模式的几种实现方式,并给出完整的案例代码。
代理模式概述
代理模式(Proxy Pattern)为其他对象提供一种代理以控制对这个对象的访问,它属于结构型设计模式。
代理模式的主要类型:
- 静态代理:在编译时确定代理类
- 动态代理(JDK):基于接口的代理
- CGLIB代理:基于继承的代理
完整案例代码
1 定义接口和真实主题
// 业务接口
public interface UserService {
void addUser(String name);
void deleteUser(String name);
String getUser(String name);
}
// 真实主题类
public class UserServiceImpl implements UserService {
@Override
public void addUser(String name) {
// 模拟业务处理
System.out.println("添加用户:" + name);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void deleteUser(String name) {
System.out.println("删除用户:" + name);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String getUser(String name) {
System.out.println("查询用户:" + name);
return name + "的信息";
}
}
2 静态代理实现
// 静态代理类
public class StaticProxy implements UserService {
private final UserService target;
public StaticProxy(UserService target) {
this.target = target;
}
@Override
public void addUser(String name) {
System.out.println("【静态代理】-开始执行添加用户操作...");
long startTime = System.currentTimeMillis();
// 调用真实对象的方法
target.addUser(name);
long endTime = System.currentTimeMillis();
System.out.println("【静态代理】-添加用户操作完成,耗时:" + (endTime - startTime) + "ms");
}
@Override
public void deleteUser(String name) {
System.out.println("【静态代理】-开始执行删除用户操作...");
long startTime = System.currentTimeMillis();
target.deleteUser(name);
long endTime = System.currentTimeMillis();
System.out.println("【静态代理】-删除用户操作完成,耗时:" + (endTime - startTime) + "ms");
}
@Override
public String getUser(String name) {
System.out.println("【静态代理】-开始执行查询用户操作...");
long startTime = System.currentTimeMillis();
String result = target.getUser(name);
long endTime = System.currentTimeMillis();
System.out.println("【静态代理】-查询用户操作完成,耗时:" + (endTime - startTime) + "ms");
return result;
}
}
3 JDK动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 动态代理类
public class DynamicProxy implements InvocationHandler {
private final Object target;
public DynamicProxy(Object target) {
this.target = target;
}
// 创建代理对象
public Object createProxy() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this
);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
System.out.println("【JDK动态代理】-" + methodName + "方法开始执行...");
long startTime = System.currentTimeMillis();
// 执行前置处理
if (args != null && args.length > 0) {
System.out.println("【JDK动态代理】-参数:");
for (Object arg : args) {
System.out.println(" " + arg);
}
}
// 调用真实对象的方法
Object result = method.invoke(target, args);
long endTime = System.currentTimeMillis();
System.out.println("【JDK动态代理】-" + methodName + "方法执行完成,耗时:" + (endTime - startTime) + "ms");
return result;
}
}
4 CGLIB代理
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
// CGLIB代理类
public class CGLIBProxy implements MethodInterceptor {
private final Object target;
public CGLIBProxy(Object target) {
this.target = target;
}
// 创建代理对象
public Object createProxy() {
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 {
String methodName = method.getName();
System.out.println("【CGLIB代理】-" + methodName + "方法开始执行...");
long startTime = System.currentTimeMillis();
// 前置处理
if (args != null && args.length > 0) {
System.out.println("【CGLIB代理】-参数:" + String.join(", ",
java.util.Arrays.stream(args).map(String::valueOf).toArray(String[]::new)));
}
// 调用真实对象的方法
Object result = proxy.invoke(target, args);
long endTime = System.currentTimeMillis();
System.out.println("【CGLIB代理】-" + methodName + "方法执行完成,耗时:" + (endTime - startTime) + "ms");
return result;
}
}
5 主测试类
public class ProxyPatternDemo {
public static void main(String[] args) {
System.out.println("========== 代理模式案例演示 ==========\n");
// 创建真实对象
UserService userService = new UserServiceImpl();
// 1. 静态代理测试
System.out.println("----- 1. 静态代理 -----");
UserService staticProxy = new StaticProxy(userService);
staticProxy.addUser("张三");
staticProxy.deleteUser("张三");
System.out.println();
// 2. JDK动态代理测试
System.out.println("----- 2. JDK动态代理 -----");
DynamicProxy dynamicProxyHandler = new DynamicProxy(userService);
UserService dynamicProxy = (UserService) dynamicProxyHandler.createProxy();
dynamicProxy.addUser("李四");
String userInfo = dynamicProxy.getUser("李四");
System.out.println("查询结果:" + userInfo);
System.out.println();
// 3. CGLIB代理测试
System.out.println("----- 3. CGLIB代理 -----");
CGLIBProxy cglibProxyHandler = new CGLIBProxy(userService);
UserServiceImpl cglibProxy = (UserServiceImpl) cglibProxyHandler.createProxy();
cglibProxy.addUser("王五");
cglibProxy.deleteUser("王五");
System.out.println();
// 4. 对比不同代理方式
compareProxies();
}
private static void compareProxies() {
System.out.println("----- 代理方式对比 -----");
System.out.println("1. 静态代理:简单直观,但每个类都需要手动创建代理类,代码重复");
System.out.println("2. JDK动态代理:基于接口,代码复用性好,但只能代理接口");
System.out.println("3. CGLIB代理:基于继承,无需接口,但性能略低于JDK代理");
}
}
6 使用场景扩展(权限控制示例)
// 权限控制的代理示例
public class PermissionProxy implements UserService {
private final UserService target;
private String currentUserRole;
public PermissionProxy(UserService target, String role) {
this.target = target;
this.currentUserRole = role;
}
@Override
public void addUser(String name) {
if ("admin".equals(currentUserRole)) {
System.out.println("【权限代理】-管理员权限验证通过,执行添加操作");
target.addUser(name);
} else {
System.out.println("【权限代理】-权限不足,无法添加用户(需要管理员权限)");
}
}
@Override
public void deleteUser(String name) {
if ("admin".equals(currentUserRole)) {
System.out.println("【权限代理】-管理员权限验证通过,执行删除操作");
target.deleteUser(name);
} else {
System.out.println("【权限代理】-权限不足,无法删除用户(需要管理员权限)");
}
}
@Override
public String getUser(String name) {
// 查询操作所有人都有权限
System.out.println("【权限代理】-权限验证通过(查询操作对所有用户开放)");
return target.getUser(name);
}
}
运行结果
========== 代理模式案例演示 ==========
----- 1. 静态代理 -----
【静态代理】-开始执行添加用户操作...
添加用户:张三
【静态代理】-添加用户操作完成,耗时:500ms
【静态代理】-开始执行删除用户操作...
删除用户:张三
【静态代理】-删除用户操作完成,耗时:300ms
----- 2. JDK动态代理 -----
【JDK动态代理】-addUser方法开始执行...
【JDK动态代理】-参数:
李四
添加用户:李四
【JDK动态代理】-addUser方法执行完成,耗时:500ms
【JDK动态代理】-getUser方法开始执行...
【JDK动态代理】-参数:
李四
查询用户:李四
【JDK动态代理】-getUser方法执行完成,耗时:0ms
查询结果:李四的信息
----- 3. CGLIB代理 -----
【CGLIB代理】-addUser方法开始执行...
【CGLIB代理】-参数:王五
添加用户:王五
【CGLIB代理】-addUser方法执行完成,耗时:500ms
【CGLIB代理】-deleteUser方法开始执行...
【CGLIB代理】-参数:王五
删除用户:王五
【CGLIB代理】-deleteUser方法执行完成,耗时:300ms
----- 代理方式对比 -----
1. 静态代理:简单直观,但每个类都需要手动创建代理类,代码重复
2. JDK动态代理:基于接口,代码复用性好,但只能代理接口
3. CGLIB代理:基于继承,无需接口,但性能略低于JDK代理
代理模式的优势和应用场景
优势:
- 职责清晰:代理类负责预处理、过滤等操作
- 扩展性好:可以在不修改目标类的情况下增加功能
- 安全性好:可以控制对目标对象的访问权限
典型应用场景:
- Spring AOP:事务管理、日志记录
- Spring MVC:拦截器
- MyBatis:Mapper接口的动态代理
- Hibernate:延迟加载
- Java RMI:远程方法调用
- 安全控制:权限验证、身份认证
注意事项:
- 静态代理类需要手动编写,会产生大量冗余代码
- JDK代理要求目标类必须实现接口
- CGLIB代理不能代理final类和方法
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播