Java动态代理案例实现
动态代理是Java中非常重要的特性,主要用于在不修改原有代码的情况下增强方法的功能,以下是完整的实现案例:

核心接口和实现类
// 1. 定义业务接口
public interface UserService {
void addUser(String username);
void deleteUser(int id);
String getUser(int id);
}
// 2. 实现类
public class UserServiceImpl implements UserService {
@Override
public void addUser(String username) {
System.out.println("添加用户: " + username);
}
@Override
public void deleteUser(int id) {
System.out.println("删除用户: " + id);
}
@Override
public String getUser(int id) {
System.out.println("获取用户: " + id);
return "User_" + id;
}
}
JDK动态代理实现
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 3. 实现InvocationHandler接口
public class LogProxyHandler implements InvocationHandler {
// 目标对象
private Object target;
public LogProxyHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置增强
System.out.println("===== 开始执行方法: " + method.getName() + " =====");
// 记录参数
if (args != null && args.length > 0) {
System.out.print("参数: ");
for (Object arg : args) {
System.out.print(arg + " ");
}
System.out.println();
}
long startTime = System.currentTimeMillis();
// 调用目标方法
Object result = method.invoke(target, args);
long endTime = System.currentTimeMillis();
// 后置增强
System.out.println("执行耗时: " + (endTime - startTime) + "ms");
System.out.println("===== 结束执行方法: " + method.getName() + " =====\n");
return result;
}
// 获取代理对象
public Object getProxy() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this
);
}
}
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,需要导入cglib依赖
public class CglibProxyHandler implements MethodInterceptor {
private Object target;
public CglibProxyHandler(Object target) {
this.target = target;
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
throws Throwable {
// 前置处理
System.out.println("CGLIB代理 - 方法执行前: " + method.getName());
// 调用目标方法
Object result = method.invoke(target, args);
// 后置处理
System.out.println("CGLIB代理 - 方法执行后: " + method.getName());
return result;
}
// 获取代理对象
public Object getProxy() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
}
测试代码
public class ProxyDemo {
public static void main(String[] args) {
// 创建目标对象
UserService userService = new UserServiceImpl();
// JDK动态代理测试
System.out.println("========== JDK动态代理 ==========");
LogProxyHandler handler = new LogProxyHandler(userService);
UserService proxyService = (UserService) handler.getProxy();
// 通过代理对象调用方法
proxyService.addUser("张三");
proxyService.deleteUser(1001);
String user = proxyService.getUser(1001);
System.out.println("返回结果: " + user);
// CGLIB动态代理测试
System.out.println("\n========== CGLIB动态代理 ==========");
CglibProxyHandler cglibHandler = new CglibProxyHandler(userService);
UserService cglibProxy = (UserService) cglibHandler.getProxy();
cglibProxy.addUser("李四");
}
}
更实用的事务代理示例
import java.sql.Connection;
public class TransactionProxy implements InvocationHandler {
private Object target;
private Connection connection;
public TransactionProxy(Object target, Connection connection) {
this.target = target;
this.connection = connection;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try {
// 开启事务
connection.setAutoCommit(false);
System.out.println("开启事务");
// 执行目标方法
result = method.invoke(target, args);
// 提交事务
connection.commit();
System.out.println("提交事务");
} catch (Exception e) {
// 回滚事务
connection.rollback();
System.out.println("回滚事务");
throw e;
} finally {
connection.setAutoCommit(true);
}
return result;
}
public Object getProxy() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this
);
}
}
Maven依赖(如果使用CGLIB)
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
关键点说明
-
JDK动态代理
- 必须实现接口
- 使用
java.lang.reflect.Proxy类 - 性能较好,原生支持
-
CGLIB动态代理
- 不需要实现接口
- 通过继承目标类实现
- 不能代理final类和方法
-
应用场景
- 日志记录
- 事务管理
- 权限控制
- 性能监控
- AOP编程
-
注意事项
- JDK代理只能代理接口方法
- CGLIB不能代理final方法
- 代理对象的equals、hashCode、toString方法会被特殊处理