
一、前言反射与动态代理是 Java 高级特性重中之重也是 Spring 框架 AOP 实现底层原理。 反射允许程序在运行时获取类信息、操作对象动态代理依托反射实现无侵入增强目标对象功能。本文结合全套代码案例系统梳理核心知识点。二、反射机制2.1 什么是反射正常编码编译期直接new 对象()正向操作。 反射程序运行阶段获取类的全部信息构造器、成员变量、成员方法并且创建对象、修改变量、执行方法。核心先拿到 Class 字节码对象一切操作基于 Class。2.2 获取 Class 对象三种方式//方式1类名.class 【编译阶段无需对象】 ClassStudent clazz1 Student.class; //方式2对象.getClass() 【必须存在实例对象】 Student s new Student(); Class? extends Student clazz2 s.getClass(); //方式3Class.forName(全类名) 【最常用配置文件加载】 Class? clazz3 Class.forName(com.itheima.reflect.Student);重点同一个类在 JVM 中只会加载一份字节码三种方式获取的Class是同一个对象。2.3 反射核心 API 总览类型Class 方法作用构造方法 ConstructorgetConstructors()getDeclaredConstructors()获取所有公共构造器 / 所有构造器包含 private成员变量 FieldgetFields()getDeclaredFields()获取所有公共成员变量 / 全部成员变量成员方法 MethodgetMethods()getDeclaredMethods()获取所有公共方法 (含继承)/ 本类全部方法⚠️getXXX()只能获取publicgetDeclaredXXX()获取本类所有权限private/protected/public。setAccessible(true)暴力反射关闭权限检查允许访问私有成员。2.4 反射实战操作1操作构造方法创建对象//获取私有构造器 ConstructorStudent cons clazz.getDeclaredConstructor(String.class); cons.setAccessible(true); //暴力访问 Student stu cons.newInstance(张三);2操作成员变量赋值、取值Field nameField clazz.getDeclaredField(name); nameField.setAccessible(true); nameField.set(stu,李四); //赋值 String name (String) nameField.get(stu); //取值3操作成员方法运行方法Method showMethod clazz.getDeclaredMethod(show,String.class); showMethod.setAccessible(true); //invoke(对象,方法参数)执行方法 Object result showMethod.invoke(stu,测试参数);2.5 反射典型应用场景框架底层Spring Bean 实例化配合配置文件读取 properties通过全类名动态创建对象通用工具序列化、ORM 框架Mybatis实体类映射2.6 反射优缺点✅优点代码灵活运行时动态操作适配各类通用框架 ❌缺点破坏封装性跳过编译检查存在一定性能损耗三、动态代理3.1 代理思想代理模式不直接操作目标对象通过代理对象中转可以在不修改原有目标代码的前提下增加额外逻辑日志、事务、权限校验也就是无侵入增强。静态代理提前写好代理类一个目标类对应一个代理类类爆炸JDK 动态代理运行时自动生成代理类依托反射实现3.2 JDK 动态代理前置条件⚠️硬性要求目标对象必须实现接口代理对象和目标对象实现同一个接口保证对外方法一致。3.3 核心 APIjava.lang.reflect.Proxypublic static Object newProxyInstance(ClassLoader loader, Class?[] interfaces, InvocationHandler h)参数说明ClassLoader目标类的类加载器interfaces目标类实现的接口数组InvocationHandler回调处理器代理执行方法时触发InvocationHandler唯一方法Object invoke(Object proxy, Method method, Object[] args)proxy生成的代理对象method当前执行的目标方法args方法入参通过method.invoke(target,args)调用真实目标方法3.4 完整代码模板//1.定义接口 public interface Star { String sing(String name); void dance(); } //2.目标实现类 public class BigStar implements Star{ Override public String sing(String name) { System.out.println(唱歌name); return 歌曲结束; } Override public void dance() { System.out.println(跳舞); } } //3.代理工具类生成代理对象 public class ProxyUtil{ public static Star createProxy(Star target){ Star proxy (Star) Proxy.newProxyInstance( BigStar.class.getClassLoader(), BigStar.class.getInterfaces(), (proxyObj, method, args) - { //增强前置逻辑 System.out.println(准备场地、收取费用); //执行目标方法 Object res method.invoke(target,args); //增强后置逻辑 System.out.println(演出结束清理场地); return res; } ); return proxy; } } //4.测试调用 public class Test{ public static void main(String[] args) { Star target new BigStar(); Star proxy ProxyUtil.createProxy(target); proxy.sing(七里香); proxy.dance(); } }3.5 动态代理核心价值这是 Spring AOP 底层实现基础 在不改动业务代码的情况下统一增加日志记录、事务控制、异常捕获、权限校验。3.6 JDK 动态代理局限只能代理实现了接口的类没有接口的类无法使用。补充CGLIB 动态代理可以直接代理类底层通过继承目标类实现。四、整体总结反射核心运行时操作 Class 字节码操纵构造器、字段、方法暴力反射setAccessible(true)突破权限限制。反射经典场景框架动态创建对象、解析实体类。JDK 动态代理基于反射实现运行时动态生成代理类实现功能增强。JDK 动态代理约束目标类必须实现接口两大特性是学习 Spring AOP、MyBatis 等主流框架必须掌握的底层基础。