本文目录导读:

我来为你展示Java动态代理的完整案例,包括JDK动态代理和CGLIB动态代理两种实现方式。
JDK动态代理(基于接口)
基础接口和实现类
// 业务接口
public interface UserService {
void addUser(String name);
String getUser(int id);
void deleteUser(int id);
}
// 业务实现类
public class UserServiceImpl implements UserService {
@Override
public void addUser(String name) {
System.out.println("添加用户: " + name);
}
@Override
public String getUser(int id) {
System.out.println("查询用户: " + id);
return "用户" + id;
}
@Override
public void deleteUser(int id) {
System.out.println("删除用户: " + id);
}
}
JDK动态代理实现
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxyFactory {
// 创建代理对象
public static Object createProxy(Object target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new LogInvocationHandler(target)
);
}
// 日志代理处理器
static class LogInvocationHandler implements InvocationHandler {
private final Object target;
public LogInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置处理
System.out.println("[JDK代理] 调用方法: " + method.getName() +
", 参数: " + java.util.Arrays.toString(args));
long startTime = System.currentTimeMillis();
// 调用目标方法
Object result = method.invoke(target, args);
// 后置处理
long endTime = System.currentTimeMillis();
System.out.println("[JDK代理] 方法执行完毕, 耗时: " + (endTime - startTime) + "ms");
return result;
}
}
}
CGLIB动态代理(基于类继承)
CGLIB依赖(Maven)
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
CGLIB动态代理实现
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxyFactory {
// 创建代理对象
public static Object createProxy(Class<?> targetClass) {
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(targetClass);
// 设置回调
enhancer.setCallback(new LogMethodInterceptor());
// 创建代理对象
return enhancer.create();
}
// 方法拦截器
static class LogMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
// 前置处理
System.out.println("[CGLIB代理] 调用方法: " + method.getName() +
", 参数: " + java.util.Arrays.toString(args));
long startTime = System.currentTimeMillis();
// 调用父类方法
Object result = proxy.invokeSuper(obj, args);
// 后置处理
long endTime = System.currentTimeMillis();
System.out.println("[CGLIB代理] 方法执行完毕, 耗时: " + (endTime - startTime) + "ms");
return result;
}
}
}
通用动态代理工具类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {
// JDK动态代理(通用)
public static <T> T createJdkProxy(T target, ProxyHandler handler) {
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
handler.before(method, args);
Object result = method.invoke(target, args);
handler.after(method, result);
return result;
}
}
);
}
// 代理处理器接口
public interface ProxyHandler {
void before(Method method, Object[] args);
void after(Method method, Object result);
}
// 使用示例
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserService proxy = createJdkProxy(userService, new ProxyHandler() {
@Override
public void before(Method method, Object[] args) {
System.out.println("【通用代理】准备调用: " + method.getName());
}
@Override
public void after(Method method, Object result) {
System.out.println("【通用代理】调用结束: " + method.getName() +
", 结果: " + result);
}
});
proxy.addUser("张三");
proxy.getUser(1);
}
}
完整测试示例
public class DynamicProxyTest {
public static void main(String[] args) {
System.out.println("=== JDK动态代理测试 ===");
testJdkProxy();
System.out.println("\n=== CGLIB动态代理测试 ===");
testCglibProxy();
System.out.println("\n=== 性能对比测试 ===");
testPerformance();
}
// JDK代理测试
private static void testJdkProxy() {
UserService userService = new UserServiceImpl();
UserService proxy = (UserService) JdkProxyFactory.createProxy(userService);
// 调用代理方法
proxy.addUser("张三");
String user = proxy.getUser(1001);
proxy.deleteUser(1001);
System.out.println("代理对象类: " + proxy.getClass().getName());
System.out.println("是否代理对象: " + Proxy.isProxyClass(proxy.getClass()));
}
// CGLIB代理测试
private static void testCglibProxy() {
UserServiceImpl proxy = (UserServiceImpl) CglibProxyFactory
.createProxy(UserServiceImpl.class);
// 调用代理方法
proxy.addUser("李四");
String user = proxy.getUser(1002);
proxy.deleteUser(1002);
System.out.println("代理对象类: " + proxy.getClass().getName());
}
// 性能对比测试
private static void testPerformance() {
final int LOOP_COUNT = 10000;
// 测试原始对象
UserService original = new UserServiceImpl();
long start = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; i++) {
original.getUser(i);
}
long originalTime = System.currentTimeMillis() - start;
// 测试JDK代理
UserService jdkProxy = (UserService) JdkProxyFactory.createProxy(original);
start = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; i++) {
jdkProxy.getUser(i);
}
long jdkTime = System.currentTimeMillis() - start;
// 测试CGLIB代理
UserServiceImpl cglibProxy = (UserServiceImpl) CglibProxyFactory
.createProxy(UserServiceImpl.class);
start = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; i++) {
cglibProxy.getUser(i);
}
long cglibTime = System.currentTimeMillis() - start;
System.out.println("原始对象耗时: " + originalTime + "ms");
System.out.println("JDK代理耗时: " + jdkTime + "ms");
System.out.println("CGLIB代理耗时: " + cglibTime + "ms");
}
}
实际应用场景示例(AOP)
import java.lang.annotation.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Log {
String value() default "";
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Transaction {
}
// 业务类
class OrderService {
@Log("创建订单")
@Transaction
public void createOrder(String orderId) {
System.out.println("创建订单: " + orderId);
}
@Log("查询订单")
public String getOrder(String orderId) {
System.out.println("查询订单: " + orderId);
return "订单信息-" + orderId;
}
@Transaction
public void cancelOrder(String orderId) {
System.out.println("取消订单: " + orderId);
}
}
// 自定义动态代理(模拟AOP)
public class AopProxy {
public static <T> T createAopProxy(T target, Class<?> targetClass) {
return (T) Proxy.newProxyInstance(
targetClass.getClassLoader(),
targetClass.getInterfaces(),
new AopInvocationHandler(target, targetClass)
);
}
static class AopInvocationHandler implements InvocationHandler {
private final Object target;
private final Class<?> targetClass;
public AopInvocationHandler(Object target, Class<?> targetClass) {
this.target = target;
this.targetClass = targetClass;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 获取原始方法(含注解)
Method originalMethod = targetClass.getMethod(method.getName(),
method.getParameterTypes());
Object result = null;
// 检查是否包含@Transaction注解
if (originalMethod.isAnnotationPresent(Transaction.class)) {
System.out.println("[事务] 开启事务");
try {
result = method.invoke(target, args);
System.out.println("[事务] 提交事务");
} catch (Exception e) {
System.out.println("[事务] 回滚事务");
throw e;
}
} else {
result = method.invoke(target, args);
}
// 检查是否包含@Log注解
if (originalMethod.isAnnotationPresent(Log.class)) {
Log log = originalMethod.getAnnotation(Log.class);
System.out.println("[日志] " + log.value() + " - " +
java.util.Arrays.toString(args));
}
return result;
}
}
public static void main(String[] args) {
// 创建代理
OrderService service = new OrderService();
OrderService proxy = createAopProxy(service, OrderService.class);
// 测试
proxy.createOrder("ORD001");
System.out.println("---");
proxy.getOrder("ORD002");
System.out.println("---");
proxy.cancelOrder("ORD003");
}
}
注意事项和最佳实践
选择建议
public class ProxySelectionGuide {
public static void main(String[] args) {
// 强烈推荐:Spring中优先使用JDK动态代理
/*
* 选择策略:
* 1. 有接口时优先使用JDK动态代理
* - 标准JDK功能,无需额外依赖
* - 性能相对较高(Java 8+)
*
* 2. 无接口或需要继承时使用CGLIB
* - 需要CGLIB依赖
* - 不能代理final类
*
* 3. 现代Spring使用
* - Spring Boot默认使用CGLIB
* - 因为CGLIB避免了类型转换问题
*/
System.out.println("动态代理选择指南");
System.out.println("=================");
System.out.println("1. 有接口: 优先JDK动态代理");
System.out.println("2. 无接口: 使用CGLIB");
System.out.println("3. Spring Boot默认: CGLIB");
}
}
-
JDK动态代理:
- 基于接口(Proxy.newProxyInstance)
- 通过InvocationHandler处理调用
- 代理对象自动继承java.lang.reflect.Proxy
-
CGLIB动态代理:
- 基于继承(Enhancer)
- 通过MethodInterceptor处理调用
- 不能代理final类和方法
-
应用场景:
- AOP编程(事务、日志)
- RPC框架
- 延迟加载
- 权限控制
- 性能监控
-
性能考虑:
- JDK代理创建对象效率高,调用时性能略低
- CGLIB创建对象效率低,调用时性能较高
- 现代JVM对JDK代理性能优化明显
这个完整案例涵盖了动态代理的主要用法,你可以根据实际需求选择合适的方式。