本文目录导读:

我来为您提供Java动态代理的完整案例代码,包括JDK动态代理和CGLIB动态代理两种方式。
JDK动态代理(基于接口)
案例:日志记录代理
// 1. 定义业务接口
public interface UserService {
void addUser(String name);
void deleteUser(int id);
String getUser(int id);
}
// 2. 实现业务接口
public class UserServiceImpl implements UserService {
@Override
public void addUser(String name) {
System.out.println("添加用户: " + name);
}
@Override
public void deleteUser(int id) {
System.out.println("删除用户, ID: " + id);
}
@Override
public String getUser(int id) {
System.out.println("查询用户, ID: " + id);
return "用户" + id;
}
}
// 3. 实现InvocationHandler接口
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class LogInvocationHandler implements InvocationHandler {
private Object target; // 目标对象
public LogInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置增强
System.out.println("======= 方法调用开始 =======");
System.out.println("调用方法: " + method.getName());
System.out.println("参数: " + Arrays.toString(args));
// 调用目标方法
Object result = method.invoke(target, args);
// 后置增强
System.out.println("返回结果: " + result);
System.out.println("======= 方法调用结束 =======");
return result;
}
// 创建代理对象的工厂方法
public static Object createProxy(Object target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new LogInvocationHandler(target)
);
}
}
// 4. 测试代码
public class JdkProxyTest {
public static void main(String[] args) {
// 创建目标对象
UserService userService = new UserServiceImpl();
// 创建代理对象
UserService proxy = (UserService) LogInvocationHandler.createProxy(userService);
// 调用代理方法
System.out.println("=== 测试添加用户 ===");
proxy.addUser("张三");
System.out.println("\n=== 测试删除用户 ===");
proxy.deleteUser(1001);
System.out.println("\n=== 测试查询用户 ===");
String user = proxy.getUser(1002);
System.out.println("最终结果: " + user);
}
}
通用JDK动态代理工具类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
public static <T> T getProxy(T target, ProxyInterceptor interceptor) {
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
(proxy, method, args) -> {
Object result = null;
if (interceptor.before(proxy, method, args)) {
result = method.invoke(target, args);
}
interceptor.after(proxy, method, args, result);
return result;
}
);
}
// 拦截器接口
public interface ProxyInterceptor {
default boolean before(Object proxy, Method method, Object[] args) {
return true;
}
default void after(Object proxy, Method method, Object[] args, Object result) {
}
}
}
// 使用示例
public class GenericProxyDemo {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
// 创建带日志的代理
UserService proxy = ProxyFactory.getProxy(userService, new ProxyFactory.ProxyInterceptor() {
@Override
public boolean before(Object proxy, Method method, Object[] args) {
System.out.println("前置处理: " + method.getName());
return true;
}
@Override
public void after(Object proxy, Method method, Object[] args, Object result) {
System.out.println("后置处理: " + method.getName() + " 结果=" + result);
}
});
proxy.addUser("李四");
}
}
CGLIB动态代理(基于继承)
// 需要引入cglib依赖
// <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;
// 1. 定义一个普通类(不需要实现接口)
class PaymentService {
public void pay(double amount) {
System.out.println("支付: " + amount + " 元");
}
public void refund(double amount) {
System.out.println("退款: " + amount + " 元");
}
public final String getServiceName() {
return "支付服务";
}
}
// 2. 实现MethodInterceptor
class PaymentInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// 前置处理
System.out.println("=== 开始执行: " + method.getName() + " ===");
System.out.println("参数: " + args[0]);
// 调用目标方法
Object result = proxy.invokeSuper(obj, args);
// 后置处理
System.out.println("=== 执行完成: " + method.getName() + " ===");
return result;
}
// 创建代理对象
public static <T> T createProxy(Class<T> targetClass) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetClass);
enhancer.setCallback(new PaymentInterceptor());
return (T) enhancer.create();
}
}
// 3. 测试CGLIB代理
public class CglibProxyDemo {
public static void main(String[] args) {
// 创建代理对象
PaymentService proxy = PaymentInterceptor.createProxy(PaymentService.class);
// 调用代理方法
proxy.pay(100.0);
System.out.println();
proxy.refund(50.0);
// 注意:final方法不会被代理
System.out.println("\n服务名称: " + proxy.getServiceName());
}
}
实际应用案例:事务管理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 定义一个简单的数据库事务管理器
class TransactionManager {
public void beginTransaction() {
System.out.println("开始事务...");
}
public void commitTransaction() {
System.out.println("提交事务...");
}
public void rollbackTransaction(Exception e) {
System.out.println("回滚事务, 异常: " + e.getMessage());
}
}
// 业务接口
interface AccountService {
void transfer(String from, String to, double amount);
}
// 业务实现类
class AccountServiceImpl implements AccountService {
@Override
public void transfer(String from, String to, double amount) {
System.out.println("从账户[" + from + "]转账给[" + to + "]金额[" + amount + "]成功");
// 模拟业务处理
// 如果金额大于10000,抛出异常模拟失败场景
if (amount > 10000) {
throw new RuntimeException("转账金额超限");
}
}
}
// 事务代理
public class TransactionProxy {
public static <T> T getTransactionProxy(T target) {
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
(proxy, method, args) -> {
TransactionManager tx = new TransactionManager();
Object result = null;
try {
tx.beginTransaction();
result = method.invoke(target, args);
tx.commitTransaction();
} catch (Exception e) {
tx.rollbackTransaction(e);
throw e;
}
return result;
}
);
}
public static void main(String[] args) {
// 创建原始对象
AccountService accountService = new AccountServiceImpl();
// 创建带事务的代理
AccountService proxy = getTransactionProxy(accountService);
// 测试成功场景
System.out.println("=== 测试正常转账 ===");
proxy.transfer("A账户", "B账户", 5000);
// 测试失败场景
System.out.println("\n=== 测试异常转账 ===");
try {
proxy.transfer("A账户", "B账户", 15000);
} catch (RuntimeException e) {
System.out.println("转账失败: " + e.getMessage());
}
}
}
JDK动态代理 vs CGLIB动态代理
public class ProxyComparison {
public static void main(String[] args) {
// JDK代理(接口代理)
System.out.println("=== JDK动态代理 ===");
UserService userService = new UserServiceImpl();
UserService jdkProxy = (UserService) LogInvocationHandler.createProxy(userService);
jdkProxy.addUser("测试JDK代理");
// CGLIB代理(类代理)
System.out.println("\n=== CGLIB动态代理 ===");
PaymentService cglibProxy = PaymentInterceptor.createProxy(PaymentService.class);
cglibProxy.pay(100);
// 关键区别
System.out.println("\n=== 关键区别 ===");
System.out.println("1. JDK代理: 基于接口实现,需要目标类实现接口");
System.out.println("2. CGLIB代理: 基于继承实现,可以代理普通类");
System.out.println("3. JDK代理: 使用java.lang.reflect.Proxy");
System.out.println("4. CGLIB代理: 使用net.sf.cglib.proxy.Enhancer");
System.out.println("5. JDK代理: 性能较高(JDK8+)");
System.out.println("6. CGLIB代理: 不能代理final类和方法");
}
}
关键说明
执行流程
-
JDK动态代理流程:
- 创建目标对象
- 创建InvocationHandler实例
- 使用Proxy.newProxyInstance创建代理对象
- 调用代理对象的方法时,会调用InvocationHandler的invoke方法
-
CGLIB动态代理流程:
- 创建Enhancer实例
- 设置父类(目标类)
- 设置MethodInterceptor回调
- 创建代理对象
使用场景
- JDK动态代理:目标类实现接口时使用;Spring等框架的默认实现
- CGLIB动态代理:目标类没有实现接口时使用;MyBatis-Spring等需要代理类的场景
选择建议
- 优先使用JDK代理,因为它更简单、性能更好
- 当目标类没有实现接口时,使用CGLIB代理
- 注意CGLIB不能代理final类和方法