✅ 动态代理
动态代理 是在程序运行时创建代理对象,不需要提前写好代理类代码。
✅ 本质:用反射机制,在运行时生成代理对象,代理目标对象的方法调用。
✅ 动态代理 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 的代理机制