第 9 周:反射 / 注解 / 动态代理与项目收尾
本周目标
本周补齐 Spring 的底层前置知识,并完成阶段二交付。完成后,应能够:
- 使用反射获取类信息、创建对象并调用方法
- 自定义注解并使用反射读取注解信息
- 使用动态代理为方法统一添加增强逻辑
- 说明单例、工厂和装饰模式的作用与写法
- 手写一个简化版 IOC/AOP,理解 Spring 的核心机制
- 整理项目文档并完成阶段二复盘
学习资料与范围
- 主课程:Java 零基础视频教程(下部)
- 视频范围:下部“高级特性”章节中的反射、注解、动态代理,以及“设计模式”章节中的单例、工厂、装饰
XML/Dom4j/XPath 本周不学,留到阶段三写 MyBatis 映射文件时再补。
需要掌握的知识点
反射
- 反射的作用:在运行时获取类信息并操作类
- 获取
Class对象的三种方式:类名.class、对象.getClass()、Class.forName() - 通过反射获取构造方法、成员方法、成员变量
- 使用
newInstance()创建对象,使用invoke()调用方法 setAccessible(true)访问私有成员及其风险- 反射的性能开销和封装破坏问题
- 通过反射读取配置文件中的实现类名并创建对象
- 类加载器读取
resources目录下配置文件的方式
注解
- 注解的作用:为代码添加元数据,供编译期或运行期处理
- 元注解:
@Target、@Retention、@Documented、@Inherited RetentionPolicy.SOURCE、CLASS、RUNTIME的区别- 定义带属性的注解并使用默认值
- 使用反射读取类、方法、字段上的注解及其属性
- 注解加反射的典型应用:自动执行被标记的方法、自动注入对象
- 常见框架注解的作用来源:
@Override、@Component、@Autowired
动态代理
- 代理模式的作用:在不修改原类的前提下增强功能
- 静态代理与动态代理的区别
- 基于接口的动态代理:
Proxy.newProxyInstance()与InvocationHandler - 在
invoke()中实现方法前后增强、参数校验、异常包装 - 动态代理只能代理接口的限制
- 动态代理与 AOP 的关系:切面、增强、目标对象
设计模式
- 单例模式:饿汉、懒汉、双重检查、静态内部类、枚举写法及其线程安全和反射风险
- 工厂模式:简单工厂、工厂方法与反射加配置的解耦方式
- 装饰模式与代理模式的区别:增强已有行为和提供代理访问
- 模式的使用原则:解决重复出现的结构问题,不为用而用
必做练习
- 反射基础:使用三种方式获取
Student的Class对象,并输出类名、包名和父类。 - 反射创建对象:通过反射调用有参构造创建学生对象,并调用
setName()和getTotalScore()。 - 反射读写字段:使用反射获取所有字段名和类型,修改一个私有字段并输出结果。
- 注解定义:定义
@AutoRun注解,只允许标注在方法上并在运行时保留。 - 注解加反射:实现一个简易运行器,扫描指定类中所有带
@AutoRun的方法并依次执行。 - 自定义注入注解:定义
@AutoWrite注解,通过反射为标注字段注入实现类实例。 - 静态代理:为学生服务编写静态代理,在方法前后输出耗时。
- 动态代理:使用
Proxy和InvocationHandler实现同样的耗时统计,对比代码量。 - 增强逻辑:在动态代理中加入参数校验,非法参数直接抛出业务异常。
- 单例改造:使用静态内部类或枚举实现
StudentDaoFactory,并用反射尝试创建第二个实例,观察防护效果。 - 工厂加配置:把持久化实现类名写入配置文件,使用反射创建实例,实现内存实现与文件实现的切换。
- 装饰模式:为学生信息的输出增加装饰类,实现带边框的内容格式化。
本周综合任务:mini IOC/AOP 版项目
在项目上实现一个简化版容器,理解 Spring 的两大核心机制。这部分是实现思路练习,不追求功能完整。
IOC 要求
- 定义
@Component注解,标注需要容器管理的类 - 定义
@Autowired注解,标注需要注入的字段 - 使用反射扫描指定包下的类,实例化带
@Component的类并放入容器 - 为标注
@Autowired的字段注入容器中的实例 - 支持通过类或接口名称从容器获取对象
- 明确说明当前版本不支持循环依赖和构造器注入
AOP 要求
- 定义
@Loggable注解,标注需要记录日志的方法 - 使用动态代理为标注方法统一添加日志和耗时统计
- 代理逻辑与业务代码完全分离,业务类不出现日志框架代码
- 对比使用代理前后业务类的代码变化
项目收尾要求
- 全部功能接入容器后,
main方法只负责启动容器和进入菜单 - 补充单元测试,保证重构后功能行为不变
- 运行
mvn package打包并独立运行验证 - 更新 README,补充项目结构、改造说明和运行方式
- 整理 Git 提交记录,为验收版本打 tag
- 完成阶段二复盘:知识清单、待补强项、项目讲解提纲和简历描述草稿
本周产出
- 反射、注解和动态代理练习代码
- 单例、工厂、装饰模式练习代码
- mini IOC/AOP 实现及说明文档
- 重构后的项目源码、单元测试和打包产物
- 更新后的 README 和 Git tag
- 阶段二复盘、面试讲解提纲和简历项目描述草稿
完成检查
- 能够使用反射创建对象、调用方法和读写字段
- 能够自定义注解并使用反射读取
- 能够说明运行期注解的必要条件
- 能够使用动态代理为方法统一增强
- 能够说明动态代理与 AOP 的关系
- 能够写出线程安全的单例并说明实现方式
- 能够使用工厂加配置切换实现类
- 已完成 mini IOC/AOP 并接入项目
- 已打包运行、更新 README 并完成阶段复盘