✅ 动态代理
动态代理 是在程序运行时创建代理对象,不需要提前写好代理类代码。
✅ 本质:用反射机制,在运行时生成代理对象,代理目标对象的方法调用。
✅ 动态代理 vs 静态代理
特性 |
静态代理 |
动态代理 |
编写方式 |
手动编写代理类 |
运行时自动生成代理类 |
灵活性 |
不够灵活,一个接口一个代理类 |
很灵活,只需一套代理逻辑 |
使用场景 |
小项目、学习 |
Spring AOP、事务、权限校验等 |
性能 |
性能好 |
性能略低(但可接受) |
✅ 动态代理的使用前提
必须基于接口编程!
目标对象要实现一个或多个接口,代理对象也实现这些接口。
✅ 动态代理的基本结构(JDK 实现)
1 2 3 4 5 6 7 8 9 10 11
| public interface UserService { void login(String username); }
public class UserServiceImpl implements UserService { public void login(String username) { System.out.println(username + " 登录成功!"); } }
|
✅ 创建动态代理对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import java.lang.reflect.*;
public class ProxyFactory { public static Object getProxy(Object target) { return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("日志:方法开始执行..."); Object result = method.invoke(target, args); System.out.println("日志:方法执行完毕。"); return result; } } ); } }
|
✅ 测试使用动态代理
1 2 3 4 5 6 7 8
| public class Test { public static void main(String[] args) { UserService target = new UserServiceImpl(); UserService proxy = (UserService) ProxyFactory.getProxy(target);
proxy.login("张三"); } }
|
✅ 输出结果
1 2 3
| 日志:方法开始执行... 张三 登录成功! 日志:方法执行完毕。
|
✅ 总结动态代理核心知识点
内容 |
说明 |
关键类 |
java.lang.reflect.Proxy |
接口 |
目标对象必须实现接口 |
回调 |
使用 InvocationHandler 实现调用逻辑 |
方法 |
invoke() 拦截所有接口方法调用 |
✅ 动态代理常见应用场景
- Spring AOP 切面(如:事务、日志、安全控制)
- RPC 框架远程方法调用
- JDK 和 MyBatis 的代理机制