1. Java 反射概述
- 定义:允许程序在运行时查询、访问和修改自身的结构和行为。
- 特点:非常有用,但需谨慎使用,可能带来性能开销和安全风险。
2. 反射的概念和用法
- Class 类:每个类都有一个 Class 类对象,用于获取类信息。
- 获取方式:直接使用类名、通过实例的
getClass()
方法、使用Class.forName()
。
- 获取方式:直接使用类名、通过实例的
- 访问字段:通过
getField()
、set()
、get()
方法。 - 访问方法:通过
getMethod()
、invoke()
方法。 - 访问构造函数:通过
getConstructor()
、newInstance()
方法。 - 注解处理:反射读取类注解,广泛应用于框架。
- 泛型和数组:反射处理泛型和数组类型。
- 安全问题:可能绕过编译时访问控制。
- 性能问题:反射操作通常比直接代码调用慢。
3. 动态代理
- 基础:反射机制是 Java 动态代理的基础。
- 实现案例:创建代理对象,为接口实现类添加额外行为。
- 使用
Proxy.newProxyInstance()
方法。 - 参数:类加载器、接口数组、
InvocationHandler
。
- 使用
4. CGLIB 动态代理
- 定义:高性能代码生成库,用于扩展 Java 类和实现接口。
- 区别:与 Java 动态代理不同,CGLIB 可代理未实现接口的类。
- 实现案例:
- 添加 CGLIB 依赖到项目。
- 使用
Enhancer
类创建代理对象。 - 参数:设置父类、回调函数(拦截器)、创建代理对象。
5. 模拟 Spring AOP 实现
- AOP:面向切面编程,分离横切关注点与业务逻辑。
- 代理机制:Spring AOP 通过 JDK 动态代理或 CGLIB 代理实现。
- 模拟实现:
- 创建服务接口和实现。
- 创建切面,添加日志方法。
- 定义
JoinPoint
接口和实现类。 - 创建
AspectProxy
类生成代理对象,应用切面逻辑。
6. 反射在开发中的实际应用场景
- 框架开发:Spring 使用反射实现依赖注入、AOP。
- 动态代理:实现方法拦截、日志记录等。
- 单元测试:访问和修改私有成员进行测试。
- 插件系统:动态加载和使用插件。
- 配置文件解析:映射配置到程序类和对象。
- 对象序列化:序列化框架使用反射动态操作属性。
- 泛型和集合操作:动态操作泛型类型和集合。
- 注解处理:读取和处理注解。
- 动态类加载:加载字节码并创建实例。
- 类型检查和转换:运行时检查和转换对象类型。
- 访问和修改私有成员:访问或修改类私有成员。
- 实现反射 API:查询类信息、创建实例、调用方法等。
- 动态调用方法:根据方法名字符串动态调用方法。
- 通用数据处理:编写通用数据访问层处理 CRUD。
- 工厂模式:根据字符串标识创建对象实例。
7. 结论
- 反射机制强大,但需注意性能和安全问题。
- 学习反射有助于理解框架底层结构,对自定义框架开发至关重要。
8. 其他
- 学习优秀框架源码有助于理解反射在实际开发中的应用。
- 许多公司基于开源框架进行二次开发,理解反射是必要的。