1. 动态代理基础
1.1 核心组件
-
Proxy
类:动态生成代理对象的工厂类,核心方法为newProxyInstance()
。 -
InvocationHandler
接口:代理逻辑的处理器,所有方法调用会转发到其invoke()
方法。
1.2 实现步骤
-
定义接口:代理基于接口实现。
public interface UserService { void addUser(String username); }
-
实现类(真实对象):
public class UserServiceImpl implements UserService { public void addUser(String username) { System.out.println("添加用户: " + username); } }
-
实现
InvocationHandler
:public class LoggingHandler implements InvocationHandler { private final Object target; public LoggingHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("方法调用前: " + method.getName()); Object result = method.invoke(target, args); System.out.println("方法调用后"); return result; } }
-
创建代理对象:
UserService realService = new UserServiceImpl(); UserService proxy = (UserService) Proxy.newProxyInstance( realService.getClass().getClassLoader(), new Class[]{UserService.class}, new LoggingHandler(realService) ); proxy.addUser("Alice");
1.3 底层原理
-
动态生成代理类:运行时生成
$ProxyN
类字节码。 -
方法调用流程:代理类方法调用委托给
InvocationHandler
。
1.4 应用场景
-
日志记录、性能监控、事务管理、权限控制等横切关注点。
-
RPC 框架中的远程调用封装。
1.5 优缺点
优点 | 缺点 |
---|---|
业务逻辑与切面逻辑解耦 | 仅支持接口代理 |
无需为每个类编写静态代理 | 反射调用存在性能开销 |
1.6 高级话题
-
CGLIB 代理:通过继承实现类代理(需引入
cglib
依赖)。 -
Lambda 简化:Java 8+ 使用 Lambda 表达式定义
InvocationHandler
。UserService proxy = (UserService) Proxy.newProxyInstance( loader, new Class[]{UserService.class}, (p, method, args) -> { System.out.println("Lambda 代理逻辑"); return method.invoke(target, args); } )