news 2026/6/15 21:30:55

Spring IoC 与 DI 核心原理学习笔记(根据黑马课程ssm笔记总结)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring IoC 与 DI 核心原理学习笔记(根据黑马课程ssm笔记总结)

Spring IoC 与 DI 核心原理学习笔记

一、什么是 IoC(Inversion of Control,控制反转)

1. IoC 的思想

IoC(控制反转)是一种设计思想,它将原本由程序自身控制的对象创建与依赖管理,交给容器来完成

原本:对象自己new依赖
现在:由 IoC 容器统一创建和维护对象之间的关系

2. IoC 解决了什么问题?

  • 降低代码之间的耦合度
  • 提高代码的可维护性
  • 更方便进行单元测试
  • 对象生命周期由容器统一管理

二、IoC 在 Spring 中的体现

在 Spring 中,IoC 容器负责:

  • 创建 Bean 对象
  • 管理 Bean 的生命周期
  • 维护 Bean 之间的依赖关系

示例:传统方式的问题

publicclassBookServiceImplimplementsBookService{privateBookDaobookDao=newBookDaoImpl();@Overridepublicvoidsave(){bookDao.save();}}

问题:

  • BookService强依赖BookDaoImpl
  • 一旦 DAO 实现发生变化,需要修改 Service 源码
  • 耦合度过高

三、DI(Dependency Injection,依赖注入)

1. 什么是 DI?

DI 是 IoC 的具体实现方式,用于在运行时将对象所依赖的其他对象注入进来。

IoC 是思想,DI 是实现

2. 为什么需要 DI?

业务层(Service)通常依赖 DAO 层的数据支持,而 DAO 层在 Spring 中同样作为 Bean 统一管理。
IoC 容器负责将Service 与其依赖的 DAO 自动“装配”在一起


四、使用 Spring + XML 实现 DI

1. 删除new,使用 setter 注入

Service 类
publicclassBookServiceImplimplementsBookService{privateBookDaobookDao;publicvoidsetBookDao(BookDaobookDao){this.bookDao=bookDao;}@Overridepublicvoidsave(){bookDao.save();}}

2. XML 中的配置

<beanid="bookDao"class="com.itheima.dao.impl.BookDaoImpl"/><beanid="bookService"class="com.itheima.service.impl.BookServiceImpl"><propertyname="bookDao"ref="bookDao"/></bean>

这样:

  • Service 不再关心 DAO 的具体实现
  • 依赖关系由 Spring 容器维护

五、Bean 的别名(alias)

Spring 中的 Bean 是可以起别名的:

<aliasname="bookService"alias="service"/>

之后可以通过service获取同一个 Bean 实例。


六、Bean 的作用范围(Scope)

1. 默认作用域:singleton

  • Spring 中Bean 默认是单例的
  • 适合被频繁复用的对象(如 Service、DAO)
<beanid="bookDao"class="com.itheima.dao.impl.BookDaoImpl"scope="singleton"/>

2. prototype(多例)

<beanid="bookDao"class="com.itheima.dao.impl.BookDaoImpl"scope="prototype"/>

每次获取都会创建一个新的对象。


七、Spring 创建 Bean 的底层原理

1. 使用反射创建对象

Spring 底层通过反射机制创建 Bean:

  • 构造方法可以是publicprivate
  • 默认使用无参构造方法

⚠️ 如果类中只有有参构造而没有无参构造,会抛出异常。


八、Spring 中实例化 Bean 的四种方式

方式一:构造方法(常用)

publicclassBookDaoImplimplementsBookDao{publicBookDaoImpl(){System.out.println("BookDao constructor running...");}@Overridepublicvoidsave(){System.out.println("book dao save...");}}
<beanid="bookDao"class="com.itheima.dao.impl.BookDaoImpl"/>

方式二:静态工厂(了解)

工厂类
publicclassOrderDaoFactory{publicstaticOrderDaogetOrderDao(){returnnewOrderDaoImpl();}}
XML 配置
<beanid="orderDao"class="com.itheima.factory.OrderDaoFactory"factory-method="getOrderDao"/>

方式三:实例工厂(了解)

工厂类
publicclassUserDaoFactory{publicUserDaogetUserDao(){returnnewUserDaoImpl();}}
XML 配置
<beanid="userDaoFactory"class="com.itheima.factory.UserDaoFactory"/><beanid="userDao"factory-bean="userDaoFactory"factory-method="getUserDao"/>

方式四:FactoryBean(推荐)

FactoryBean 实现类
publicclassUserDaoFactoryBeanimplementsFactoryBean<UserDao>{@OverridepublicUserDaogetObject(){returnnewUserDaoImpl();}@OverridepublicClass<?>getObjectType(){returnUserDao.class;}}
XML 配置
<beanid="userDao"class="com.itheima.factory.UserDaoFactoryBean"/>

九、总结

  • IoC:控制反转,是一种设计思想

  • DI:依赖注入,是 IoC 的具体实现

  • Spring 容器:

    • 创建对象
    • 管理依赖
    • 维护生命周期
  • Bean 默认是单例

  • 实例化 Bean 有4 种方式

  • 推荐使用:

    • 构造方法
    • FactoryBean

掌握 IoC 与 DI,是理解 Spring 框架的核心基础。


十、实例化 Bean 的三种方式(一):构造方法(常用)

1. 构造方法实例化说明

Spring 在默认情况下,通过反射调用类的无参构造方法来创建 Bean 对象

只要类中:

  • 提供了可访问的构造方法
  • 并且存在无参构造

Spring 就可以正常完成 Bean 的实例化。

2. 示例代码

Bean 类
publicclassBookDaoImplimplementsBookDao{publicBookDaoImpl(){System.out.println("book constructor is running...");}@Overridepublicvoidsave(){System.out.println("book dao save...");}}
XML 配置
<beanid="bookDao"class="com.itheima.dao.impl.BookDaoImpl"/>

3. 注意事项(面试高频)

⚠️如果无参构造方法不存在,将抛出异常:

BeanCreationException

原因:

  • Spring 默认使用无参构造方法创建对象
  • 没有无参构造,反射无法实例化 Bean

✅ 解决方式:

  • 提供无参构造方法
  • 或使用构造参数注入(后续章节)

十一、Bean 的生命周期(重点)

Bean 的生命周期描述了Bean 从创建到销毁的完整过程

1. Bean 生命周期整体流程

(1)初始化容器阶段
  1. 创建对象(分配内存)
  2. 执行构造方法
  3. 执行属性注入(set方法)
  4. 执行 Bean 初始化方法
(2)使用 Bean 阶段
  • 执行业务逻辑方法
(3)销毁容器阶段
  1. 执行 Bean 销毁方法
  2. 释放资源

📌简化记忆口诀:

构造 → 注入 → 初始化 → 使用 → 销毁


十二、Bean 销毁时机与容器关闭

1. Bean 销毁触发条件

  • 容器关闭时,才会触发 Bean 的销毁
  • 销毁方法不会自动执行,必须显式关闭容器

2. 容器关闭的两种方式

方式一:手动关闭容器(常见)
publicclassAppForLifeCycle{publicstaticvoidmain(String[]args){ConfigurableApplicationContextctx=newClassPathXmlApplicationContext("applicationContext.xml");ctx.close();}}
  • 调用close()方法
  • 立即触发 Bean 的销毁逻辑

方式二:注册 JVM 关闭钩子(推荐)
ctx.registerShutdownHook();

特点:

  • JVM 退出前自动关闭 Spring 容器
  • 常用于 Web 项目 / 长时间运行程序

十三、Bean 生命周期的控制方式

1. 通过 XML 配置生命周期方法(常用)

Bean 类
publicclassBookDaoImpl{publicvoidinit(){System.out.println("bean init...");}publicvoiddestroy(){System.out.println("bean destroy...");}}
XML 配置
<beanid="bookDao"class="com.itheima.dao.impl.BookDaoImpl"init-method="init"destroy-method="destroy"/>

2. 通过接口控制生命周期(了解)

初始化接口
publicclassBookDaoImplimplementsInitializingBean{@OverridepublicvoidafterPropertiesSet(){System.out.println("after properties set...");}}
销毁接口
publicclassBookDaoImplimplementsDisposableBean{@Overridepublicvoiddestroy(){System.out.println("bean destroy...");}}

📌实际开发建议:

  • ✅ 优先使用init-method/destroy-method
  • ❌ 尽量避免侵入业务代码的接口方式

十四、小结

  • Spring 默认通过无参构造方法实例化 Bean

  • Bean 生命周期五步:

    1. 构造
    2. 属性注入
    3. 初始化
    4. 使用
    5. 销毁
  • Bean 销毁必须关闭容器

  • 生命周期控制方式:

    • XML(推荐)
    • 接口(了解)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 13:52:07

小白必看!大模型开发工程师技能图谱与学习路径,建议收藏

文章详细介绍了后端工程师转行AI大模型工程化工程师所需的知识体系&#xff0c;包括Python、深度学习框架、Transformer架构、训练微调技术、RAG等关键技术。作者强调掌握AI技术对个人竞争力的提升作用&#xff0c;并提供AI大模型学习资源&#xff0c;包括思维导图、书籍、视频…

作者头像 李华
网站建设 2026/6/15 11:20:14

PyTorch-CUDA-v2.7镜像能否优化物流路径规划

PyTorch-CUDA-v2.7镜像能否优化物流路径规划 在现代智能物流系统的演进中&#xff0c;一个看似技术底层的问题正悄然影响着整个供应链的效率边界&#xff1a;我们能否用AI真正“理解”一条最优路径&#xff1f; 传统的路径规划依赖于图搜索算法和启发式规则&#xff0c;在面对城…

作者头像 李华
网站建设 2026/6/15 13:39:59

正则表达式^是干啥的?一篇文章让你搞懂

正则表达式是现代编程中处理文本的核心工具之一&#xff0c;它通过一套简洁而强大的语法规则&#xff0c;能精准地匹配、查找、替换或提取字符串。掌握它&#xff0c;意味着你获得了一把高效解决复杂文本问题的钥匙。然而&#xff0c;其陡峭的学习曲线和容易出错的特性也让许多…

作者头像 李华
网站建设 2026/6/15 13:18:29

PyTorch-CUDA镜像能否用于金融量化模型训练

PyTorch-CUDA镜像能否用于金融量化模型训练 在高频交易的战场上&#xff0c;每一毫秒都可能决定盈亏。而在这背后&#xff0c;是成百上千次模型迭代积累出的微弱优势——谁能更快地验证一个因子假设、更迅速地训练出新的预测模型&#xff0c;谁就更有可能抓住市场中稍纵即逝的套…

作者头像 李华
网站建设 2026/6/15 12:18:39

PyTorch-CUDA-v2.7镜像能否用于虚假新闻检测

PyTorch-CUDA-v2.7 镜像能否用于虚假新闻检测 在信息爆炸的时代&#xff0c;一条未经核实的消息可能在几分钟内传遍全球。社交媒体平台上的“标题党”、伪造信源、断章取义等内容层出不穷&#xff0c;不仅误导公众认知&#xff0c;甚至影响金融市场与政治局势。面对这一挑战&a…

作者头像 李华