Java动态代理使用指南
动态代理是Java中非常强大的特性,允许在运行时动态创建代理类并拦截方法调用,主要有两种实现方式:

JDK动态代理(基于接口)
JDK动态代理要求目标对象必须实现接口。
示例:用户管理系统的日志代理
// 1. 定义业务接口
public interface UserService {
void addUser(String username);
void deleteUser(int id);
String getUserInfo(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: " + id);
}
@Override
public String getUserInfo(int id) {
return "用户信息: ID=" + id;
}
}
// 3. 实现InvocationHandler(代理逻辑)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
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("[日志] 调用方法: " + method.getName() +
", 参数: " + java.util.Arrays.toString(args));
// 调用目标方法
Object result = method.invoke(target, args);
// 后置增强:记录结果
System.out.println("[日志] 方法执行完成,返回值: " + result);
return result;
}
}
// 4. 客户端使用
public class DynamicProxyDemo {
public static void main(String[] args) {
// 创建目标对象
UserService userService = new UserServiceImpl();
// 创建InvocationHandler
LogInvocationHandler handler = new LogInvocationHandler(userService);
// 创建代理对象
UserService proxy = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(), // 类加载器
userService.getClass().getInterfaces(), // 接口列表
handler // 调用处理器
);
// 通过代理对象调用方法
proxy.addUser("张三");
System.out.println("---");
proxy.deleteUser(1001);
System.out.println("---");
String info = proxy.getUserInfo(2002);
System.out.println(info);
}
}
CGLIB动态代理(基于继承)
CGLIB可以代理没有实现接口的类。
// 导入CGLIB包(需要额外引入cglib依赖)
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
// 1. 目标类(无需实现接口)
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
}
// 2. 实现MethodInterceptor
public class LogMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("[日志] 执行方法: " + method.getName() +
", 参数: " + Arrays.toString(args));
// 调用父类方法
Object result = proxy.invokeSuper(obj, args);
System.out.println("[日志] 方法返回: " + result);
return result;
}
}
// 3. 使用CGLIB创建代理
public class CglibProxyDemo {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
// 设置父类(目标类)
enhancer.setSuperclass(Calculator.class);
// 设置回调方法拦截器
enhancer.setCallback(new LogMethodInterceptor());
// 创建代理对象
Calculator proxy = (Calculator) enhancer.create();
// 通过代理调用方法
System.out.println("结果: " + proxy.add(10, 20));
System.out.println("---");
System.out.println("结果: " + proxy.subtract(50, 30));
}
}
实际应用场景
场景1:事务管理
public class TransactionInvocationHandler implements InvocationHandler {
private Object target;
private TransactionManager transactionManager;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// 开启事务
transactionManager.beginTransaction();
// 调用业务方法
Object result = method.invoke(target, args);
// 提交事务
transactionManager.commit();
return result;
} catch (Exception e) {
// 回滚事务
transactionManager.rollback();
throw e;
}
}
}
场景2:权限控制
public class SecurityInvocationHandler implements InvocationHandler {
private Object target;
private User currentUser;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 检查是否需要权限
if (method.isAnnotationPresent(RequirePermission.class)) {
RequirePermission permission = method.getAnnotation(RequirePermission.class);
if (!currentUser.hasPermission(permission.value())) {
throw new SecurityException("权限不足");
}
}
return method.invoke(target, args);
}
}
优缺点对比
JDK动态代理:
- ✅ 优点:Java原生支持,无需额外依赖
- ❌ 缺点:只能代理实现了接口的类
CGLIB动态代理:
- ✅ 优点:可以代理普通类
- ❌ 缺点:需要额外引入cglib依赖,不能代理final类和方法
最佳实践建议
- 优先使用JDK动态代理,除非需要代理没有接口的类
- Spring Framework中默认使用JDK动态代理,如果目标类没有实现接口则使用CGLIB
- 注意性能:频繁创建代理对象可能影响性能,考虑缓存代理对象
- 代理链:可以组合多个InvocationHandler实现复杂代理逻辑
希望这些示例能帮助你理解Java动态代理的使用!
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播