学习日记-spring-day45-7.10
知识点:
1.初始化Bean单例池 完成getBean createBean(1)
知识点 | 核心内容 | 重点 |
单例词初始化 | 在容器初始化阶段预先创建单例对象,避免在getBean时动态创建 | 单例词必须在容器初始化时完成加载,否则会触发异常 |
getBean方法逻辑 | 1. 从beanDefinitionMap查询BeanDefinition 2. 根据scope判断单例/多例 3. 单例:直接从单例词获取 4. 多例:反射动态创建新对象 | 多例模式每次调用getBean都会生成新实例,需与单例严格区分 |
异常处理机制 | 未找到BeanDefinition时抛出异常(如空指针),单例词缺失需检查初始化代码 | 异常类型选择需符合业务逻辑,单例词完整性是关键验证点 |
反射创建对象 | 通过BeanDefinition中的Class对象反射实例化,支持多例模式动态生成 | 反射性能开销较高,需注意多例场景的并发控制 |
流程图解逻辑 | 1. 查询BeanDefinition → 2. 判断scope → 3. 单例词/反射分支处理 | 分支优先级:单例词检查 > 多例创建 > 异常兜底 |
2.初始化Bean单例池 完成getBean createBean(2)
知识点 | 核心内容 | 重点 |
反射创建对象 | 通过bin definition对象动态创建实例,使用getDeclaredConstructor()和newInstance()实现反射 | 构造器参数处理(当前未实现,但预留扩展) |
方法设计逻辑 | createBin方法返回Object类型,兼容未知返回类型场景 | 异常处理(反射失败返回null) |
命名规范 | 修改名称bin definition by scan以增强可读性 | 作用域(scope)与Class对象的关联理解 |
代码分层思想 | 区分单例初始化与动态实例化场景 | 反射底层一致性(单例/多例均依赖反射) |
3.初始化Bean单例池 完成getBean createBean(3)
知识点 | 核心内容 | 重点 |
单例池初始化 | 通过反射创建bean实例并初始化单例池 | 单例与多例(prototype)的判断逻辑 |
BeanDefinition解析 | 从BeanDefinitionMap获取bean定义信息 | getScope()方法获取作用域类型 |
集合遍历技术 | 使用Enumeration遍历Map集合 | hasMoreElements()和nextElement()方法使用 |
依赖注入时机 | 容器创建完成后立即初始化单例bean | 构造器执行时机与扫描完成标志 |
命名规范处理 | bean名称大小写忽略的兼容处理 | 默认命名规则与自定义名称冲突 |
测试验证方法 | 通过单例池objects集合验证实例化结果 | 动态修改bean名称的测试技巧 |
4.初始化Bean单例池 完成getBean createBean(4)
知识点 | 核心内容 | 重点 |
getBin方法实现 | 根据bean名称从单例池或创建新实例返回对象 | 单例与多实例的判断逻辑(scope值比较) |
单例模式处理 | 从singletonObjects直接获取已创建实例 | 必须确保单例bean已预先存入单例池 |
原型模式处理 | 每次调用createBean创建新实例 | 反射生成对象的性能消耗 |
异常处理机制 | 不存在的bean抛出NullPointerException | 可扩展为自定义异常类型 |
scope配置验证 | 未配置scope时默认单例模式 | prototype配置导致每次获取不同实例 |
类型转换处理 | Object返回值需要显式类型转换 | 类型安全校验缺失风险 |
容器初始化验证 | beanDefinitionMap必须预先加载定义 | 定义缺失会导致空指针异常 |
测试用例设计 | 通过重复获取验证单例/原型效果 | 边界测试(不存在的bean名) |
5.实现依赖注入(1)
知识点 | 核心内容 | 重点 |
依赖注入概念 | 组件间存在依赖关系时由Spring容器自动装配属性 | 区分@Autowired按名称注入与按类型注入的区别 |
注解实现 | 自定义@Autowired注解实现依赖注入功能 | 注解修饰字段与setter方法的区别 |
反射机制应用 | 通过Class对象获取字段并检查注解修饰情况 | 字段访问权限处理与类型匹配验证 |
容器扩展点 | 在createBean方法中植入依赖注入逻辑 | 属性注入时机(实例化后/初始化前) |
装配策略 | 默认按名称匹配的依赖解析机制 | 循环依赖的检测与处理 |
6.实现依赖注入(2)
知识点 | 核心内容 | 重点 |
自定义注解实现 | 创建@AutoWired注解实现依赖注入功能 | 注解属性required的作用与默认值设置 |
依赖注入机制 | 通过容器完成字段属性自动装配 | 按名称匹配与其他匹配方式的区别 |
注解作用域控制 | 限定注解仅作用于字段(FIELD) | 原生注解功能裁剪策略 |
空指针异常验证 | 未注入时调用方法抛出NullPointerException | 异常触发条件与调试方法 |
测试验证流程 | 通过hi()方法验证注入结果 | 服务层与DAO层调用链验证 |
7.实现依赖注入(3)
知识点 | 核心内容 | 关键代码/操作 | 难点 |
反射机制应用 | 通过反射遍历类字段并处理注解 | getDeclaredFields()获取所有字段 isAnnotationPresent(AutoWired.class)检查注解 | 私有字段访问需调用setAccessible(true)进行爆破 |
依赖注入实现 | 按名称自动装配对象 | getBean(fieldName)获取依赖对象 field.set(instance, bean)注入属性 | 多实例与单例处理逻辑差异 |
注解属性处理 | 解析@AutoWired的required属性 | getAnnotation(AutoWired.class).required()获取配置值 | required=true时必须成功注入的校验逻辑 |
异常处理机制 | 非法访问异常解决方案 | 字段爆破代码示例: declaredField.setAccessible(true) | 反射操作中的权限控制要点 |
对象装配流程 | 完整依赖注入链路 | 1. 字段扫描→2. 注解检查→3. 实例获取→4. 属性设置 | 循环依赖问题的潜在风险 |
8.实现BeanPostProcessor机制(1)
知识点 | 核心内容 | 重点 |
Spring 依赖注入 | 实现任务阶段四的依赖注入机制 | 容器管理对象的生命周期 |
Bean 后置处理器 | 实现 BeanPostProcessor 接口的两个核心方法:postProcessBeforeInitialization 和 postProcessAfterInitialization | 方法调用时机(初始化前后)和 作用范围(针对所有 Bean) |
原生 Spring 后置处理器案例 | 通过 IDE 演示原生后置处理器的配置与使用 | 接口方法重写的业务逻辑实现 |
自定义 Bean 后置处理器 | 实现 Spring 扩展功能的核心机制,支持多后置处理器链式调用 | 处理顺序 和 容器集成逻辑 |
AOP 机制铺垫 | 后置处理器完成后将进入 AOP 功能开发 | 与后置处理器的关联性 |
9.实现BeanPostProcessor机制(2)
知识点 | 核心内容 | 重点 |
Spring后置处理器机制 | 通过InitializingBean接口实现初始化方法,在setter方法后调用afterPropertiesSet() | 初始化方法执行时机(setter后 vs. 后置处理器before/after方法) |
Bean生命周期阶段 | 构造器→setter→初始化方法→后置处理器after方法 | 无初始化方法时后置处理器仍会执行before/after |
接口InitializingBean作用 | 提供afterPropertiesSet()方法,等价于XML配置的init-method | 需实现接口 vs. XML配置的灵活性对比 |
后置处理器与初始化方法关系 | 后置处理器before在初始化方法前执行,after在之后执行 | 执行顺序逻辑(容器自动调用) |
代码实现示例 | MonsterService实现InitializingBean并重写afterPropertiesSet() | 方法调用由容器控制(非主动调用) |
10.实现BeanPostProcessor机制(3)
知识点 | 核心内容 | 重点 |
接口编程概念 | 通过判断类是否实现特定接口来决定是否执行业务逻辑 | 标记接口(无方法的接口)与普通接口的区别 |
instanceof操作符 | 判断对象运行类型是否为某类型或其子类型 | 接口实现类也属于接口的子类型 |
Spring容器初始化机制 | 在bean实例化后通过InitializingBean接口执行afterPropertiesSet()方法 | 初始化时机(在set方法执行完毕后) |
标记接口应用 | Serializable等无方法接口的底层判断用途 | 标记接口与普通功能接口的设计差异 |
类型转换与异常处理 | 将bean实例强制转换为接口类型调用初始化方法 | ClassCastException风险处理 |
容器生命周期控制 | 在createBean方法中实现初始化逻辑判断 | 反射机制与接口回调的结合应用 |
11.实现BeanPostProcessor机制(4)
知识点 | 核心内容 | 重点 |
Bean后置处理器概念 | 介绍如何自定义实现Spring的BeanPostProcessor接口 | 接口的两个默认方法区别(before/after initialization) |
postProcessBeforeInitialization方法 | 在bean初始化方法前调用的拦截逻辑 | 方法执行时机与AOP切面编程的关系 |
postProcessBeforeInitialization方法 | 在bean初始化方法后调用的拦截逻辑 | 返回值处理与bean生命周期关系 |
后置处理器注册机制 | 必须通过@Component注解将处理器注册为Spring bean | 未注册时的表现与错误排查 |
原生Spring对比 | 演示自定义实现与原生BeanPostProcessor的异同点 | 方法签名一致性要求 |
切面编程概念 | 后置处理器对所有bean生效的切面特性 | 与AspectJ注解方式的区别 |
12.实现BeanPostProcessor机制(5)
知识点 | 核心内容 | 重点 |
后置处理器机制 | Spring容器中后置处理器的实现逻辑与多实例管理 | 多个后置处理器的注入与调用顺序 |
接口实现判断 | 使用Class.isAssignableFrom()而非instanceof判断类对象是否实现接口 | 类对象 vs 实例对象的判断方法差异 |
容器简化设计 | 将后置处理器单独存入ArrayList而非原生单例池 | 简化逻辑与原Spring容器的差异 |
动态加载逻辑 | 在scan方法中识别并实例化后置处理器组件 | @Component与后置处理器的特殊处理 |
集合管理策略 | 通过binPostProcessorList集中管理后置处理器实例 | 集合与单例池的取舍逻辑 |
13.实现BeanPostProcessor机制(6)
知识点 | 核心内容 | 重点 |
Spring容器初始化机制 | 后置处理器(BeanPostProcessor)在Bean初始化方法前后的调用逻辑(before/after方法) | before方法可修改Bean实例并返回新对象,after方法同理 |
Bean生命周期控制 | 在createBean方法中实现初始化方法前后的拦截逻辑 | 初始化方法调用顺序:后置处理器before → 初始化方法 → 后置处理器after |
后置处理器实现细节 | 通过遍历BeanPostProcessor集合动态处理Bean实例 | 易混淆点:后置处理器需避免重复注册(单例池与ArrayList的冲突) |
简化容器设计 | 使用ArrayList替代单例池存储后置处理器以降低复杂度 | 关键优化:跳过冗余的create方法调用 |
调试与验证 | 通过断点调试验证后置处理器调用链的正确性 | 重点:确保before/after方法返回值正确处理Bean实例 |
14.实现BeanPostProcessor机制(7)
知识点 | 核心内容 | 重点 |
Spring后置处理器 | 通过实现InitializingBean接口和配置@Component验证car类的初始化方法及后置处理器调用逻辑 | 后置处理器的before方法针对容器内所有Bean生效,需注意作用范围与类型判断逻辑 |
切面编程概念 | 后置处理器可对多个对象操作(如统一处理car类),实现类似AOP的切面功能 | 与普通对象编程的区别:切面编程的核心是跨对象操作(如日志、权限、事务等) |
类型判断与动态处理 | 在后置处理器中通过instanceof判断car类型并单独处理,演示类型转换与方法调用 | 动态处理时机:需明确在before方法中处理还是在初始化后处理 |
Spring容器机制 | 验证@Component注解的自动装配及InitializingBean接口的初始化回调 | 易混淆点:initializingBean接口与@PostConstruct注解的优先级差异 |
业务逻辑分层 | 演示如何在后置处理器中分门别类处理不同Bean(如car与monsterService) | 关键逻辑:通过条件分支实现差异化处理,避免全量拦截影响性能 |
15.实现BeanPostProcessor机制(8)
知识点 | 核心内容 | 重点 |
Spring容器配置方式 | 通过XML或注解配置Spring容器,理解底层机制可提升掌控力 | @Autowired注解的底层实现 vs 表面使用 |
Bean装配原理 | 从BeanPostProcessor到createBean的调用链,需传递beanName参数 | 方法参数顺序错误导致编译报错 |
调试技巧 | 通过IDE错误定位(红线提示)快速修复参数传递问题 | beanName传递位置(需与createBean定义一致) |
16.实现BeanPostProcessor机制(9)
知识点 | 核心内容 | 重点 |
后置处理器机制 | 讲解Spring后置处理器对Bean实例的处理逻辑,包括空值返回时的容错机制 | 空值处理逻辑(原生Spring容器自动回退到原实例) |
源码调试技巧 | 通过Debug演示后置处理器before方法的执行流程,分析current对象判空逻辑 | 断点追踪时机(需关注return null时的分支跳转) |
代码改进实践 | 手动实现类似Spring的判空容错逻辑:if(current!=null) then modify instance | 自定义容器与原生的差异(需显式判空避免NPE) |
AOP关联机制 | 提及后置处理器与AOP的协同关系(未展开) | 扩展点(需结合后续AOP机制理解) |