Spring IOC基于XML和注解管理Bean

IoC 是 Inversion of Control 的简写,译为“ 控制反转 ”,它不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则,能够指导我们如何设计出 松耦合、更优良的程序。

Spring 通过 IoC 容器来管理所有 Java 对象的实例化和初始化,控制对象与对象之间的依赖关系。将由 IoC 容器管理的 Java 对象称为 Spring Bean,它与使用关键字 new 创建的 Java 对象没有任何区别。

IoC 容器是 Spring 框架中最重要的核心组件之一,它贯穿了 Spring 从诞生到成长的整个过程。

IOC容器

1.控制反转,依赖注入

控制反转(Inversion of Control,简称IoC)是一种软件设计原则,它将传统的程序控制流程反转过来,即由被调用者控制调用者的执行过程。这样做的好处在于降低了代码之间的耦合性,使得代码更加灵活、可维护和可扩展。

一个典型的控制反转例子是使用依赖注入(Dependency Injection,简称DI)。依赖注入是控制反转的一种实现方式,它通过将依赖关系从代码内部移动到外部来实现解耦。

假设我们有一个简单的应用程序,其中包含一个服务类 MessageService 负责发送消息,并且这个服务类依赖于一个用于实际发送消息的 MessageSender 接口。在传统的实现中,MessageService 通常会直接创建一个特定的 MessageSender 实例,但在使用控制反转的思想下,我们会将 MessageSender 的创建和注入从 MessageService 中分离出来。

传统实现(无控制反转):

public class MessageService {private MessageSender messageSender;public MessageService() {// 在构造函数中直接实例化特定的 MessageSender 实例this.messageSender = new EmailMessageSender(); // 假设使用 EmailMessageSender 发送消息}public void sendMessage(String message) {messageSender.send(message);}
}

使用控制反转(依赖注入):

public class MessageService {private MessageSender messageSender;public MessageService(MessageSender messageSender) {// 通过构造函数接收一个 MessageSender 实例,由外部注入this.messageSender = messageSender;}public void sendMessage(String message) {messageSender.send(message);}
}

现在,使用控制反转,我们将 MessageSender 的实例化过程交由调用者来完成。这样做的好处是,在应用程序的其他地方,我们可以根据需要轻松地更换不同的 MessageSender 实现(例如,使用短信发送消息而不是电子邮件),而无需修改 MessageService 的代码。同时,这也使得单元测试变得更容易,因为我们可以轻松地注入一个模拟的 MessageSender 实例来进行测试。

举例:
如果你希望在使用短信发送消息而不是电子邮件时进行更改,只需更改 MessageService 类的构造函数中注入的 MessageSender 实例即可。这就是控制反转的好处,它使得我们可以在应用程序的其他地方配置不同的实现,并且只需更改依赖注入的部分,而不需要修改 MessageService 的实现代码。

让我们看一下如何在 MessageService 中使用短信发送消息的例子:

  • 创建一个用于发送短信的实现类 SmsMessageSender:
public class SmsMessageSender implements MessageSender {public void send(String message) {// 实现发送短信的逻辑System.out.println("Sending SMS: " + message);}
}
  • 现在,在使用 MessageService 的地方,通过构造函数将 SmsMessageSender 注入:
public class MyApp {public static void main(String[] args) {// 使用短信发送消息MessageSender smsSender = new SmsMessageSender();MessageService messageService = new MessageService(smsSender);// 发送消息messageService.sendMessage("Hello, this is a text message!");}
}

通过这样的更改,MessageService 现在使用 SmsMessageSender 来发送消息而不是之前的 EmailMessageSender,而且这个更改只发生在应用程序的一个地方,使得代码更易于维护和扩展。同时,你可以根据需要在其他地方继续使用 EmailMessageSender,并且无需对 MessageService 的实现进行任何修改。

set注入和依赖注入

在依赖注入(Dependency Injection,DI)的实践中,有两种常见的注入方式:构造函数注入(Constructor Injection)和属性/方法注入(Setter Injection)。

构造函数注入(Constructor Injection):
构造函数注入是将依赖通过类的构造函数传递进来的方式。在这种注入方式中,类的依赖关系在创建对象时就被明确地传递给对象,保证了对象在被实例化后就具备了所需的依赖。这种注入方式通常被认为是推荐的注入方式,因为它在对象创建过程中就明确了依赖关系,使得对象在创建后处于一种可用的状态。
示例:构造函数注入的Java代码

public class MessageService {private MessageSender messageSender;public MessageService(MessageSender messageSender) {this.messageSender = messageSender;}// 业务逻辑方法使用依赖发送消息public void sendMessage(String message) {messageSender.send(message);}
}

属性/方法注入(Setter Injection):
属性/方法注入是通过setter方法或者普通方法将依赖传递给对象的方式。在这种注入方式中,对象首先由默认构造函数创建,然后通过setter方法或者普通方法设置其依赖。由于依赖在创建对象后才被注入,因此在对象实例化时,它可能处于不完整或不可用的状态,这是它与构造函数注入的主要区别。
示例:属性/方法注入的Java代码

public class MessageService {private MessageSender messageSender;// 通过setter方法注入依赖public void setMessageSender(MessageSender messageSender) {this.messageSender = messageSender;}// 业务逻辑方法使用依赖发送消息public void sendMessage(String message) {messageSender.send(message);}
}

需要注意的是,属性/方法注入可能导致对象处于不完整或不可用的状态,因此需要在使用对象之前确保其依赖已经被正确注入。另一方面,构造函数注入在对象创建时就明确了依赖关系,因此更容易维护和确保对象的完整性。

通常情况下,如果可能,推荐使用构造函数注入,因为它更符合依赖注入的原则,能够在对象创建时就将依赖传递进来,减少了对象的不稳定性。而属性/方法注入则适用于一些特殊情况,例如使用框架进行依赖注入时可能更为便利,或者在某些场景下灵活性要求较高时使用。

2.IoC容器在Spring的实现

Spring 的 IoC 容器就是 IoC思想的一个落地的产品实现。IoC容器中管理的组件也叫做 bean。在创建 bean 之前,首先需要创建IoC 容器。Spring 提供了IoC 容器的两种实现方式:

①BeanFactory

这是 IoC 容器的基本实现,是 Spring 内部使用的接口。面向 Spring 本身,不提供给开发人员使用。

②ApplicationContext

BeanFactory 的子接口,提供了更多高级特性。面向 Spring 的使用者,几乎所有场合都使用 ApplicationContext 而不是底层的 BeanFactory。

③ApplicationContext的主要实现类
在这里插入图片描述

类型名简介
ClassPathXmlApplicationContext通过读取类路径下的 XML 格式的配置文件创建 IOC 容器对象
FileSystemXmlApplicationContext通过文件系统路径读取 XML 格式的配置文件创建 IOC 容器对象
ConfigurableApplicationContextApplicationContext 的子接口,包含一些扩展方法 refresh() 和 close() ,让 ApplicationContext 具有启动、关闭和刷新上下文的能力。
WebApplicationContext专门为 Web 应用准备,基于 Web 环境创建 IOC 容器对象,并将对象引入存入 ServletContext 域中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1474995.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【Unity】在Unity中制作一个小车游戏

目录 第一步:设置Unity项目 第二步:设置场景 第三步:添加车辆控制脚本 第四步:将脚本附加到车辆上 第五步:运行和测试 第六步:添加更多功能(可选) 在Unity中制作一个小车游戏…

webGL可用的14种3D文件格式,但要具体问题具体分析。

hello,我威斯数据,你在网上看到的各种炫酷的3d交互效果,背后都必须有三维文件支撑,就好比你网页的时候,得有设计稿源文件一样。WebGL是一种基于OpenGL ES 2.0标准的3D图形库,可以在网页上实现硬件加速的3D图…

MySQL之备份与恢复和MySQL用户工具(一)

备份与恢复 备份脚本化 为备份写一些脚本是标准做法。展示一个示例程序,其中必定有很多辅助内容,这只会增加篇幅,在这里我们更愿意列举一些典型的备份脚本功能,展示一些Perl脚本的代码片段。你可以把这些当作可重用的代码块&…

算法012:将x减到0的最小操作数

将x减到0的最小操作数. - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/minimum-operations-to-reduce-x-to-zero/ 这个题使用到的是滑动窗口。 乍一看&#xff0c…

web安全基础名词概念

本节内容根据小迪安全讲解制作 第一天 域名: 1.1什么是域名? 网域名称(英语:Domain Name,简称:Domain),简称域名、网域,是由一串用点分隔的字符组成的互联网上某一台计算机或计算机组的名称&a…

【系统架构设计师】八、系统工程基础知识(系统工程|系统性能)

目录 一、系统工程 1.1 系统工程的方法 1.1.1 霍尔的三维结构 1.1.2 切克兰德方法 1.1.3 并行工程方法 1.1.4 综合集成法 1.1.5.WSR 系统方法。 二、系统工程生命周期 2.1 系统工程生命周期7阶段 2.2 生命周期方法 三、基于模型的系统工程(MBSE) 四、系统性能 4.1…

昇思大模型第19天打卡|SSD目标检测

模型简介 SSD,全称Single Shot MultiBox Detector,是Wei Liu在ECCV 2016上提出的一种目标检测算法。使用Nvidia Titan X在VOC 2007测试集上,SSD对于输入尺寸300x300的网络,达到74.3%mAP(mean Average Precision)以及59FPS&#xf…

LeetCode 189.轮转数组 三段逆置 C写法

LeetCode 189.轮转数组 C写法 三段逆置 思路: 三段逆置方法:先逆置前n-k个 再逆置后k个 最后整体逆置 由示例1得,需要先逆置1,2,3,4 再逆置5,6,7,最后前n-k个与后k个逆置 代码 void reverse(int*num, int left, int right) //逆置函数 { while(left …

【qt】获取主机信息系统

话不多说,先一睹芳颜! 如果你也想达到这种效果,那咱们就开始吧! 目录 一.登录界面设计1.ui登录设计 二.加载界面1.lineEdit的密码输入模式2.lineEdit按回车跳转的信号3.密码的判断4.创建加载界面5.创建定时器来进行进度条的移动6.定时器执行的槽函数 三.主机信息界面1.主机信息…

阶段三:项目开发---大数据开发运行环境搭建:任务3:安装配置Hadoop集群

任务描述 知识点:安装配置Hadoop 重 点: 安装配置Hadoop 难 点:无 内 容: Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威…

深度卷积神经网络 AlexNet

一、机器学习深度学习的发展 1、机器学习SVM方法 (1)20世纪90年代,基于统计学习理论的结果,开发了一种新型的学习算法——支持向量机(SVM)。这就产生了一类新的理论上优雅的学习机器,它们将SVM…

【智能算法应用】灰狼算法求解二维栅格路径规划问题

目录 1.算法原理2.二维路径规划数学模型3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】灰狼算法(GWO)原理及实现 2.二维路径规划数学模型 栅格法模型最早由 W.E. Howden 于 1968 年提出,障碍物的栅格用黑色表示,可通…

【数据结构与算法】详解二叉树下:实践篇————通过链式结构深入理解并实现二叉树

💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《数据结构与算法》 期待您的关注 ​ 目录 一、二叉树前置知识 二、二叉树链式结构实现的结构定义 三、二叉树的基本实现 &…

仿哔哩哔哩视频app小程序模板源码

仿哔哩哔哩视频app小程序模板源码 粉色的哔哩哔哩手机视频网页,多媒体视频类微信小程序ui前端模板下载。包含:视频主页和播放详情页。 仿哔哩哔哩视频app小程序模板源码

【漏洞复现】方正全媒体采编系统——SQL注入

声明:本文档或演示材料仅供教育和教学目的使用,任何个人或组织使用本文档中的信息进行非法活动,均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 方正全媒体采编系统(FZMediaEditor)是一…

短信群发平台适用于哪些行业?

短信群发平台作为一种高效、快速且成本相对较低的通信方式,适用于多个行业。以下是一些主要适用行业的概述: 1. 零售与电商行业 应用场景:零售和电商企业可以利用短信群发进行新品推广、促销信息发布、订单状态更新、物流跟踪通知等。 2. 金…

【ARMv8/v9 GIC 系列 1.7 -- GIC PPI | SPI | SGI | LPI 中断使能配置介绍】

请阅读【ARM GICv3/v4 实战学习 】 文章目录 GIC 各种中断使能配置PPIs(每个处理器私有中断)SPIs(共享外设中断)SGIs(软件生成的中断)LPIs(局部中断)GIC 各种中断使能配置 在ARM GICv3和GICv4架构中,不同类型的中断(如PPIs、SPIs、SGIs和LPIs)可以通过不同的方式进…

springboot331+vue“有光”摄影分享网站系统+论文+源码+讲解

第3章 系统分析 3.1 可行性分析 3.1.1技术可行性 研发设计程序流程挑选面向对象设计、功能齐全、简单实用的Java编程设计核心理念。MySQL数据库存储数据。Idea工具作为编程软件,win10计算机操作系统作为应用系统,以及数据库可视化工具等技术职称。一般…

STM32自己从零开始实操08:STM32主控原理图

由于老师使用的各引脚分门别类的单片机原理图我没有找到,我使用是引脚按顺序摆放的,不方便一个模块一个模块截图展示,所以这部分使用老师的原理图。 一、电源 1.1电源的介绍 1.1.1数字电源和地(VDD和VSS) 数字电源…

FlinkCDC-3.1.1 DataStream Source

问题&#xff1a; Caused by: java.lang.ClassNotFoundException: org.apache.flink.table.catalog.ObjectPath 解决&#xff1a; 在poml文件中&#xff0c;导入的flink-table依赖把“ <scope>”去掉 <properties><maven.compiler.source>8</maven.compi…