学习日记-spring-day35-6.23

发布于:2025-06-24 ⋅ 阅读:(15) ⋅ 点赞:(0)

知识点:


1.实现简单基于XML配置程序 Dom4j回顾

知识点

核心内容

重点

DOM Forge

用于解析XML文件(如web.xml),涉及Document对象、根元素获取及子元素遍历

XML解析流程(SAXReader→Document→rootElement→子节点)

Tomcat底层实现

手动模拟Tomcat机制,解析web.xml初始化容器

init方法中的路径处理与元素遍历逻辑

螺旋递增学习模式

前后知识点关联

回顾students.xml解析案例

代码复用

复用历史代码(如SAXReader解析工具)

类路径获取与文档对象构建的代码逻辑

2.实现简单基于XML配置程序 代码实现(1)

知识点

核心内容

重点

Spring容器简单实现机制

通过DOM解析XML配置文件并反射生成对象

单例对象池使用ConcurrentHashMap存储

DOM4J解析XML

获取类路径→创建SAXReader→获取Document对象→提取根元素

节点属性获取顺序与XML结构对应关系

反射机制应用

通过类全路径创建对象实例

属性注入时需注意类型转换(如String转Integer)

项目依赖管理

JAR包引入的两种状态(已识别/未识别)

Project Structure中Add as Library关键操作

代码复用原则

合理复用历史代码的实践方法

路径处理时需注意相对路径与绝对路径区别

异常处理策略

构造器异常直接向上抛出

配置文件加载失败的常见原因排查

测试驱动开发

通过分段输出验证各环节数据准确性

XPath表达式与elements()方法的选择

3.实现简单基于XML配置程序 代码实现(2)

知识点

核心内容

重点

反射机制

通过Class.forName()获取类对象,使用newInstance()创建实例

反射创建的对象属性为默认值,需手动赋值

Spring容器流程

1. 解析XML配置

2. 反射创建对象

3. 属性赋值

4. 存入单例池

bin ID与对象属性ID的区别

对象属性赋值

可通过反射getDeclaredMethods()遍历并调用invoke()赋值

实际Spring底层通过动态机制(非硬编码)实现

单例池管理

使用singletonObjects.put(id, object)存储实例

容器ID vs 对象属性ID的区分

简化实现目的

聚焦核心流程(解析→创建→赋值→存储),暂不处理BeanDefinition等复杂逻辑

后续结合AOP/IOC进阶完善

4.Spring原生容器结构梳理

知识点

核心内容

重点

Spring容器底层结构

IOC容器类型为ClassPathXmlApplicationContext,包含BeanDefinitionMap存储Bean配置信息

BeanDefinitionMap与单例池singletonObjects的关系

BeanDefinition存储方式

通过ConcurrentHashMap的Node数组(默认512大小)存储,包含Bean的ID、类名、懒加载等属性

哈希冲突处理(next指针链表结构)

单例池机制

DefaultListableBeanFactory中的singletonObjects(ConcurrentHashMap类型)缓存已实例化的单例Bean

初始化顺序(系统默认Bean vs 配置Bean)

属性注入结构

PropertyValues通过ArrayList存储Bean属性(如monsterId、name等)

XML配置与实际对象属性的映射逻辑

Debug分析技巧

通过断点追踪BeanDefinitionMap和singletonObjects的实时状态

容器启动阶段(Bean定义加载 vs 实例化阶段)

5. 例题:不指定ID问题

题目解析:

  • 配置情况:在beans.xml中注入2个Monster对象但未指定id属性

  • 问题1:运行是否会报错

  • 问题2:若不报错如何获取自动分配的id

  • 解题要点:

    • 配置差异:两个Monster对象的属性值存在明显区别(monsterId分别为1010和666,name和skill值也有不同)

    • 关键考察:Spring容器对未指定id的bean的处理机制

    • 获取方法:需要通过特定方式获取容器自动生成的bean名称

  • 注意事项:

    • 这是故意设计的特殊场景,实际开发中通常应显式指定id

    • 需要理解Spring底层容器结构才能正确解答

6.例题解答

知识点

核心内容

重点

Spring容器ID分配机制

未显式分配ID时,系统会按全类名#序号规则自动分配(如com.example.Monster#0)

自动分配规则 vs 显式ID配置

Debug验证方法

通过断点查看beanDefinitionMap中的存储结构,验证自动ID分配规则

容器结构查看技巧

自动分配ID获取方式

使用getBean("全类名#0")获取首个未显式配置ID的bean

动态获取与静态配置的区别

实际开发建议

演示场景故意移除ID配置,但生产环境必须显式配置

演示与实际应用差异

对象属性验证

通过输出monster01.getId()验证自动分配bean的属性值正确性

对象属性与容器ID的关联

7. 例题:配置Car对象

题目解析

  • 练习目标:创建一个Car类并通过Spring IOC容器管理该对象

  • 具体要求:

    • 创建Car类,包含三个属性:id、name、price

    • 编写IOC容器配置文件(XML格式)

    • 在配置文件中定义Car对象的bean

    • 通过Java程序从容器获取该bean并输出

  • 实现步骤:

    • 类定义:创建Car类时应包含完整属性及getter/setter方法

    • XML配置:

      • 使用<bean>标签定义Car对象

      • 通过<property>标签为各属性赋值

    • 容器操作:

      • 使用ApplicationContext接口获取容器实例

      • 调用getBean()方法获取Car对象实例

  • 注意事项:

    • 属性赋值需遵循Spring的依赖注入规范

    • 配置文件路径需与Java代码中的路径一致

    • bean的id/name需与getBean()参数匹配

  • 底层原理:

    • 练习涉及Spring原生容器的基本结构

    • 通过XML配置实现对象创建和属性注入

    • 演示了IOC控制反转的基本实现方式

8.例题解答

知识点

核心内容

重点

Java类创建与配置

新建Car类,包含id、name、price属性,提供全属性构造器和无参构造器

无参构造器必要性(容器反射依赖默认构造器)

Spring IoC容器配置

通过XML文件(car.beans)配置Car对象属性(如id="car01", name="宝马", price=1000000)

配置文件路径与ID匹配(需与代码中getBean调用一致)

属性注入与输出验证

通过getBean获取配置的Car对象,并输出属性值(如car01.getName()返回"宝马")

属性值注入格式(XML中property标签的value赋值)

调试与异常处理

演示移除无参构造器后的报错场景,强调错误原因

异常类型识别(BeanCreationException)

9.Spring配置Bean的基本介绍

知识点

核心内容

重点

Spring IOC

依赖注入的多种形式与实现原理

IOC容器的工作机制 vs 传统对象创建方式

Bean管理

创建Bean对象与属性注入的多种方式

XML配置与注解方式的优先级差异

XML配置

基础用法与高级配置形式(如复杂属性注入)

<bean>标签的scope属性理解

注解配置

@Component、@Autowired等核心注解

注解扫描范围的配置陷阱

配置方式对比

XML的显式声明 vs 注解的隐式装配

混合使用时的冲突解决

10.通过类型来获取Bean

知识点

核心内容

重点

基于XML配置的Spring IOC容器

讲解通过XML配置Spring Bean的两种方式:ID获取类型获取

类型获取的局限性(同类Bean需唯一)

通过ID获取Bean

使用getBean(String id)方法,需在XML中明确配置Bean的ID属性

容器底层结构分析与ID命名规范

通过类型获取Bean

使用getBean(Class<T> type)方法,要求同类Bean唯一

NoUniqueBeanDefinitionException异常场景演示

单例模式应用场景

控制器(Controller)或服务层(Service)等单线程单实例场景推荐使用类型获取

多实例需求时需改用ID获取

XML配置语法细节

Bean的默认ID生成规则(全类名#编号)与显式ID覆盖

未保存配置导致的问题演示

11.Spring底层给bean对象属性赋值使用的是setter方法

知识点

核心内容

重点

Spring容器属性赋值机制

底层通过setter方法完成属性注入

必须提供对应属性的setter方法否则报错

反射赋值原理

Spring通过反射调用setter方法实现属性赋值

方法命名规范(set+属性名首字母大写)

错误验证案例

移除Car类的setName方法导致容器初始化失败

错误信息关键字段"no setter method"

设计约束

所有需要依赖注入的属性必须配套setter方法

方法可见性要求(public修饰符)


网站公告

今日签到

点亮在社区的每一天
去签到