Spring IOC基于XML和注解管理Bean

news2024/10/6 2:08:02

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.coloradmin.cn/o/1903824.html

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

相关文章

【国产AI绘图】快手把“可图”大模型开源了,这是一款支持中文的SDXL模型

Kolors 是由 Kuaishou Kolors 团队(快手可图)开发的基于潜在扩散的大规模文本到图像生成模型。经过数十亿对文本图像的训练,Kolors 在视觉质量、复杂语义的准确性以及中英文字符的文本渲染方面,与开源和专有模型相比都具有显著优势…

【LInux】从动态库的加载深入理解页表机制

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …

YOLOv8改进---BiFPN特征融合

一、BiFPN原理 1.1 基本原理 BiFPN(Bidirectional Feature Pyramid Network),双向特征金字塔网络是一种高效的多尺度特征融合网络,其基本原理概括分为以下几点: 双向特征融合:BiFPN允许特征在自顶向下和自…

DAY21-力扣刷题

1.买卖股票的最佳时机 121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int maxProfit(int[] prices) {int minpriceInteger.MAX_VALUE;int maxprofit0;for(int i0;i<prices.length;i){if(prices[i]<minprice){minpriceprices[…

【面试八股文】java基础知识

引言 本文是java面试时的一些常见知识点总结归纳和一些拓展&#xff0c;笔者在学习这些内容时&#xff0c;特地整理记录下来&#xff0c;以供大家学习共勉。 一、数据类型 1.1 为什么要设计封装类&#xff0c;Integer和int区别是什么&#xff1f; 使用封装类的目的 对象化:…

Webpack安装以及快速入门

3 Webpack 1 什么是Webpack https://webpack.js.org/ (官网) webpack 是一个现代 javascript 应用程序的 静态模块打包器 (module bundler) 待会要学的 vue-cli 脚手架环境, 集成了 webpack, 所以才能对各类文件进行打包处理 webpack是一个 静态模块 打包器,可以做以下的这…

数据自动备份方法分享!

现在很多朋友对于第三方软件颇为青睐&#xff0c;因为它们具备许多电脑自带备份工具所不具备的功能。例如&#xff0c;自动备份数据的需求。尽管你已经备份了电脑数据&#xff0c;但日常使用中数据常会增加&#xff0c;你可能无暇顾及每天的备份工作。因此&#xff0c;使用数据…

C++ 引用做函数返回值

作用&#xff1a;引用是可以作为函数的返回值存在的 注意&#xff1a;不要返回局部变量引用 用法&#xff1a;函数调用作为左值 示例&#xff1a; 运行结果&#xff1a;

cs231n作业1——KNN

参考文章&#xff1a;assignment1——KNN KNN 测试时分别计算测试样本和训练集中的每个样本的距离&#xff0c;然后选取距离最近的k个样本的标签信息来进行分类。 方法1&#xff1a;Two Loops for i in range(num_test):for j in range(num_train):dist X[i, :] - self.X…

昇思25天学习打卡营第19天 | RNN实现情感分类

RNN实现情感分类 概述 情感分类是自然语言处理中的经典任务&#xff0c;是典型的分类问题。本节使用MindSpore实现一个基于RNN网络的情感分类模型&#xff0c;实现如下的效果&#xff1a; 输入: This film is terrible 正确标签: Negative 预测标签: Negative输入: This fil…

Vue3+.NET6前后端分离式管理后台实战(二十八)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战(二十八)

初阶数据结构 二叉树常用函数(二)

函数一 求二叉树第K层的节点个数 还是一样 我们假设 K就是等于一 如果说是一个空数的话就返回0 如果说有值的话就返回一个1就可以 假设这个这层既不为空 又不是第K层的话 那么就说明第K层肯定是子树下面 那么就说明是左右子树的第&#xff08;K-1&#xff09;层 那么只将…

系统化学习 H264视频编码(02) I帧 P帧 B帧 引入及相关概念解读

说明&#xff1a;我们参考黄金圈学习法&#xff08;什么是黄金圈法则?->模型 黄金圈法则&#xff0c;本文使用&#xff1a;why-what&#xff09;来学习音H264视频编码。本系列文章侧重于理解视频编码的知识体系和实践方法&#xff0c;理论方面会更多地讲清楚 音视频中概念的…

STM32-Unix时间戳和BKP备份寄存器以及RTC实时时钟

本内容基于江协科技STM32视频学习之后整理而得。 文章目录 1. Unix时间戳1.1 Unix时间戳简介1.2 UTC/GMT1.3 时间戳转换 2. BKP备份寄存器2.1 BKP简介2.2 BKP基本结构2.3 BKP库函数 3. RTC实时时钟3.1 RTC简介3.2 RTC框图3.3 RTC基本结构3.4 硬件电路3.5 RTC操作注意事项3.6 R…

使用qt creator配置msvc环境(不需要安装shit一样的宇宙第一IDE vs的哈)

1. 背景 习惯使用Qt编程的童鞋&#xff0c;尤其是linux下开发Qt的童鞋一般都是使用qt creator作为首选IDE的&#xff0c;通常在windows上使用Qt用qt creator作为IDE的话一般编译器有mingw和msvc两种&#xff0c;使用mingw版本和在linux下的方式基本上一样十分简单&#xff0c;不…

在linux系统centos上面安装php7gmp扩展

ps:在ubuntu上面安装gmp(最简单) $ sudo apt-get install php7.0-gmp然后再php.ini添加extensionphp_gmp.so <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<…

论文略读: LLaMA Pro: Progressive LLaMA with Block Expansion

ACL 2024 人类通常在不损害旧技能的情况下获得新技能 然而&#xff0c;对于大型语言模型&#xff08;LLMs&#xff09;&#xff0c;例如从LLaMA到CodeLLaMA&#xff0c;情况正好相反。深度学习笔记&#xff1a;灾难性遗忘-CSDN博客——>论文提出了一种用于LLMs的新的预训练…

移动硬盘“需格式化”预警:专业数据恢复指南

移动硬盘“需格式化”危机&#xff1a;了解背后的真相 在日常的数字生活中&#xff0c;移动硬盘作为我们存储重要数据的“保险箱”&#xff0c;其稳定性与安全性直接关系到我们信息的完整与便捷访问。然而&#xff0c;当您尝试打开移动硬盘时&#xff0c;屏幕上赫然出现的“需…

Ubantu22.04 通过FlatPak安装微信

Ubuntu22.04 下使用Flatpak稳定安装微信&#xff01; 国际惯例&#xff0c;废话不多说&#xff0c;先上效果图。为啥使用Flatpak,因为Wechat官方只在FlatPak发布了最新的版本。之前使用了Wine以及Dock安装Wechat,效果都不是很理想&#xff0c;bug很多。所以使用了FlatPak。 Fl…

恢复出厂设置手机变成砖

上周&#xff0c;许多Google Pixel 6&#xff08;6、6a、6 Pro&#xff09;手机用户在恢复出厂设置后都面临着设备冻结的问题。 用户说他们在下载过程中遇到了丢失 tune2fs 文件的错误 。 这会导致屏幕显示以下消息&#xff1a;“Android 系统无法启动。您的数据可能会被损坏…