本文目录导读:

我来为你详细介绍Java代理模式的案例编写,包含静态代理和动态代理两种实现方式。
代理模式基础结构
定义核心接口和实现类:
// 1. 抽象主题接口
public interface Subject {
void request(String param);
String process(String data);
}
// 2. 真实主题实现类
public class RealSubject implements Subject {
@Override
public void request(String param) {
System.out.println("RealSubject处理请求: " + param);
// 模拟业务处理
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String process(String data) {
System.out.println("RealSubject处理数据: " + data);
return "Processed: " + data.toUpperCase();
}
}
静态代理实现
// 3. 静态代理类
public class StaticProxy implements Subject {
private Subject realSubject;
public StaticProxy() {
this.realSubject = new RealSubject();
}
// 前置增强
private void before() {
System.out.println("[静态代理] 前置处理:记录日志、开启事务等");
}
// 后置增强
private void after() {
System.out.println("[静态代理] 后置处理:提交事务、记录结果等");
}
@Override
public void request(String param) {
before();
try {
realSubject.request(param);
} catch (Exception e) {
System.out.println("[静态代理] 异常处理:" + e.getMessage());
} finally {
after();
}
}
@Override
public String process(String data) {
before();
String result = null;
try {
result = realSubject.process(data);
System.out.println("[静态代理] 处理结果: " + result);
} catch (Exception e) {
System.out.println("[静态代理] 异常处理:" + e.getMessage());
} finally {
after();
}
return result;
}
// 扩展功能:访问控制
public void secureRequest(String param, boolean hasPermission) {
if (!hasPermission) {
System.out.println("[静态代理] 访问被拒绝:无权限");
return;
}
request(param);
}
}
JDK动态代理实现
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 4. JDK动态代理处理器
public class DynamicProxyHandler implements InvocationHandler {
private Object target; // 目标对象
private String proxyName;
public DynamicProxyHandler(Object target) {
this.target = target;
this.proxyName = "DynamicProxy";
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("[" + proxyName + "] 代理方法: " + method.getName());
// 前置增强
before(method, args);
Object result = null;
try {
// 调用目标方法
result = method.invoke(target, args);
// 后置增强
after(method, result);
} catch (Exception e) {
// 异常增强
exception(method, e);
throw e;
}
return result;
}
private void before(Method method, Object[] args) {
System.out.println("[" + proxyName + "] 前置处理");
System.out.println("[" + proxyName + "] 参数: " + (args != null ? java.util.Arrays.toString(args) : "无"));
}
private void after(Method method, Object result) {
System.out.println("[" + proxyName + "] 后置处理");
if (result != null) {
System.out.println("[" + proxyName + "] 返回值: " + result);
}
}
private void exception(Method method, Exception e) {
System.out.println("[" + proxyName + "] 异常处理: " + e.getMessage());
}
// 创建代理对象
@SuppressWarnings("unchecked")
public static <T> T createProxy(T target) {
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new DynamicProxyHandler(target)
);
}
}
CGLIB动态代理实现(需要cglib依赖)
<!-- pom.xml 添加依赖 -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
// 5. CGLIB动态代理(可以代理没有接口的类)
public class CglibProxy implements MethodInterceptor {
private String proxyName;
public CglibProxy() {
this.proxyName = "CglibProxy";
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
throws Throwable {
System.out.println("[" + proxyName + "] 开始执行: " + method.getName());
// 前置处理
long startTime = System.currentTimeMillis();
Object result = null;
try {
// 调用父类方法
result = proxy.invokeSuper(obj, args);
// 后置处理
long endTime = System.currentTimeMillis();
System.out.println("[" + proxyName + "] 执行耗时: " + (endTime - startTime) + "ms");
} catch (Exception e) {
System.out.println("[" + proxyName + "] 异常: " + e.getMessage());
throw e;
}
return result;
}
// 创建代理对象
@SuppressWarnings("unchecked")
public static <T> T createProxy(T target) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(new CglibProxy());
return (T) enhancer.create();
}
}
实际应用案例:数据库连接池代理
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
// 6. 数据库连接池代理
public class ConnectionPoolProxy {
private List<Connection> connectionPool = new ArrayList<>();
private static final int POOL_SIZE = 5;
private static final String URL = "jdbc:mysql://localhost:3306/test";
private static final String USER = "root";
private static final String PASSWORD = "password";
public ConnectionPoolProxy() {
initializePool();
}
private void initializePool() {
for (int i = 0; i < POOL_SIZE; i++) {
connectionPool.add(createRealConnection());
}
}
private Connection createRealConnection() {
try {
return DriverManager.getConnection(URL, USER, PASSWORD);
} catch (SQLException e) {
throw new RuntimeException("创建数据库连接失败", e);
}
}
// 获取代理连接
public Connection getConnection() {
if (connectionPool.isEmpty()) {
System.out.println("连接池为空,创建新连接");
return createConnectionProxy(createRealConnection());
}
Connection realConn = connectionPool.remove(0);
System.out.println("从连接池获取连接,剩余: " + connectionPool.size());
return createConnectionProxy(realConn);
}
// 创建连接的代理对象
private Connection createConnectionProxy(Connection realConnection) {
// 使用JDK动态代理创建Connection的代理
return (Connection) Proxy.newProxyInstance(
Connection.class.getClassLoader(),
new Class[]{Connection.class},
new ConnectionProxyHandler(realConnection)
);
}
// 连接代理处理器
private class ConnectionProxyHandler implements InvocationHandler {
private Connection realConnection;
private boolean closed = false;
public ConnectionProxyHandler(Connection realConnection) {
this.realConnection = realConnection;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
// 拦截close方法,将连接归还到连接池
if ("close".equals(methodName)) {
if (!closed) {
closed = true;
connectionPool.add(realConnection);
System.out.println("连接归还到连接池,当前池大小: " + connectionPool.size());
}
return null;
}
// 如果连接已关闭,拒绝其他操作
if (closed) {
throw new SQLException("连接已关闭");
}
// 执行实际方法
return method.invoke(realConnection, args);
}
}
}
测试代码
public class ProxyPatternTest {
public static void main(String[] args) {
System.out.println("========== 1. 静态代理测试 ==========");
testStaticProxy();
System.out.println("\n========== 2. JDK动态代理测试 ==========");
testDynamicProxy();
System.out.println("\n========== 3. CGLIB代理测试 ==========");
testCglibProxy();
}
// 测试静态代理
private static void testStaticProxy() {
StaticProxy proxy = new StaticProxy();
proxy.request("静态代理请求");
System.out.println("---");
proxy.secureRequest("需要权限的请求", true);
proxy.secureRequest("无权限请求", false);
}
// 测试JDK动态代理
private static void testDynamicProxy() {
RealSubject realSubject = new RealSubject();
Subject proxy = DynamicProxyHandler.createProxy(realSubject);
proxy.request("动态代理请求");
System.out.println("---");
String result = proxy.process("hello world");
System.out.println("最终结果: " + result);
}
// 测试CGLIB代理
private static void testCglibProxy() {
RealSubject realSubject = new RealSubject();
Subject proxy = CglibProxy.createProxy(realSubject);
proxy.request("CGLIB代理请求");
System.out.println("---");
String result = proxy.process("cglib test");
System.out.println("最终结果: " + result);
// 测试没有接口的类
SimpleClass simple = CglibProxy.createProxy(new SimpleClass());
simple.doSomething();
}
// 用于测试CGLIB的无接口类
static class SimpleClass {
public void doSomething() {
System.out.println("SimpleClass执行操作");
}
}
}
三种代理模式对比
| 特性 | 静态代理 | JDK动态代理 | CGLIB动态代理 |
|---|---|---|---|
| 实现方式 | 手动编写代理类 | 自动生成代理类 | 自动生成子类 |
| 是否需接口 | 是 | 是 | 否 |
| 性能 | 较好 | 一般 | 较好 |
| 灵活性 | 差 | 好 | 好 |
| 适用范围 | 简单场景 | 有接口的场景 | 无接口或需更高性能 |
最佳实践建议
-
选择依据:
- 有接口:优先使用JDK动态代理
- 无接口或需性能:使用CGLIB
- 简单场景:考虑静态代理
-
应用场景:
- AOP(面向切面编程)
- 事务管理
- 权限控制
- 日志记录
- 性能监控
- 延迟加载
-
注意事项:
- 动态代理的性能开销
- 代理对象的序列化问题
- 不要对final类使用CGLIB
- 注意代理链的顺序
这个案例涵盖了Java代理模式的主要实现方式,你可以根据实际需求选择合适的实现方案。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播