Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第 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 的关系:切面、增强、目标对象

设计模式

  • 单例模式:饿汉、懒汉、双重检查、静态内部类、枚举写法及其线程安全和反射风险
  • 工厂模式:简单工厂、工厂方法与反射加配置的解耦方式
  • 装饰模式与代理模式的区别:增强已有行为和提供代理访问
  • 模式的使用原则:解决重复出现的结构问题,不为用而用

必做练习

  1. 反射基础:使用三种方式获取 Student 的 Class 对象,并输出类名、包名和父类。
  2. 反射创建对象:通过反射调用有参构造创建学生对象,并调用 setName() 和 getTotalScore()。
  3. 反射读写字段:使用反射获取所有字段名和类型,修改一个私有字段并输出结果。
  4. 注解定义:定义 @AutoRun 注解,只允许标注在方法上并在运行时保留。
  5. 注解加反射:实现一个简易运行器,扫描指定类中所有带 @AutoRun 的方法并依次执行。
  6. 自定义注入注解:定义 @AutoWrite 注解,通过反射为标注字段注入实现类实例。
  7. 静态代理:为学生服务编写静态代理,在方法前后输出耗时。
  8. 动态代理:使用 Proxy 和 InvocationHandler 实现同样的耗时统计,对比代码量。
  9. 增强逻辑:在动态代理中加入参数校验,非法参数直接抛出业务异常。
  10. 单例改造:使用静态内部类或枚举实现 StudentDaoFactory,并用反射尝试创建第二个实例,观察防护效果。
  11. 工厂加配置:把持久化实现类名写入配置文件,使用反射创建实例,实现内存实现与文件实现的切换。
  12. 装饰模式:为学生信息的输出增加装饰类,实现带边框的内容格式化。

本周综合任务: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 并完成阶段复盘