当前位置: 首页 > news >正文

Spring IOC 容器:掌握 Spring 的核心技术

Spring 是一个非常流行和强大的 Java 开发框架,它可以帮助我们简化和优化 Java 项目的开发过程。Spring 的核心技术之一就是 IOC(Inversion of Control,控制反转),它可以实现对象之间的解耦,让对象的创建和管理由 Spring 容器来完成,而不是由对象自己或使用对象的类来完成。这样可以提高代码的可维护性和可扩展性,也可以方便地进行单元测试和依赖注入。

那么,Spring IOC 容器是如何工作的呢?本文将详细地介绍 Spring IOC 容器的原理和应用,掌握 Spring 的核心技术。

什么是 IOC?

IOC(Inversion of Control,控制反转)是一种设计思想,它的目的是实现对象之间的解耦,让对象的创建和管理由第三方(如 Spring 容器)来完成,而不是由对象自己或使用对象的类来完成。这样可以提高代码的可维护性和可扩展性。

为了理解 IOC 的含义,我们可以先看一个没有使用 IOC 的例子:

public class UserService {// UserService 依赖于 UserDaoprivate UserDao userDao = new UserDao();public void saveUser(User user) {// 调用 UserDao 的方法userDao.save(user);}
}

在这个例子中,UserService 类依赖于 UserDao 类,它需要在自己的内部创建 UserDao 的实例,并调用其方法。这样做有以下几个问题:

  • UserService 和 UserDao 紧密地耦合在一起,如果 UserDao 的实现方式或者构造参数发生变化,UserService 也需要修改代码来适应。
  • UserService 难以进行单元测试,因为它需要创建真实的 UserDao 实例,并依赖于数据库环境。
  • UserService 无法灵活地替换 UserDao 的实现类,比如使用不同的数据库或者框架。

那么,如果使用了 IOC 怎么样呢?我们可以看下面的例子:

public class UserService {// UserService 依赖于 UserDao 接口private UserDao userDao;// 通过构造器或者 setter 方法注入 UserDao 的实现类public UserService(UserDao userDao) {this.userDao = userDao;}public void setUserDao(UserDao userDao) {this.userDao = userDao;}public void saveUser(User user) {// 调用 UserDao 的方法userDao.save(user);}
}

在这个例子中,UserService 类只依赖于 UserDao 接口,而不是具体的实现类。UserService 不需要在自己的内部创建 UserDao 的实例,而是通过构造器或者 setter 方法注入 UserDao 的实现类。这样做有以下几个优点:

  • UserService 和 UserDao 松散地耦合在一起,如果 UserDao 的实现方式或者构造参数发生变化,UserService 不需要修改代码来适应。
  • UserService 容易进行单元测试,因为它可以使用模拟(Mock)对象来替代真实的 UserDao 实例,并不依赖于数据库环境。
  • UserService 可以灵活地替换 UserDao 的实现类,比如使用不同的数据库或者框架。

从上面的例子可以看出,使用了 IOC 后,UserService 不再主动控制 UserDao 的创建和管理,而是交给了第三方(如 Spring 容器)来完成。这就是控制反转的含义:将对象之间的控制权从主动方转移到被动方,从而实现对象之间的解耦。

什么是 Spring IOC 容器?

Spring IOC 容器是一个用于实现 IOC 的组件,它可以创建和管理对象,以及维护对象之间的依赖关系。Spring IOC 容器的主要功能有以下几个方面:

  • 配置解析:Spring 通过 XML 或注解的方式来配置 Bean 的信息,如类名、属性、依赖等。Spring 会解析这些配置信息,并将其转换为 BeanDefinition 对象,用于描述 Bean 的元数据。BeanDefinition 对象会被注册到一个 BeanDefinitionRegistry 中,用于存储和管理 Bean 的配置信息。
  • 反射机制:Spring 通过反射机制来创建 Bean 的实例,并通过反射或动态代理来调用 Bean 的方法。反射机制使得 Spring 可以在运行时动态地操作类和对象,而不需要提前知道它们的具体信息。
  • 依赖注入:Spring 通过依赖注入(Dependency Injection,DI)来实现对象之间的依赖关系。依赖注入是指将一个对象所需要的其他对象(即依赖对象)通过配置或者代码的方式传递给该对象,而不是让该对象自己去创建或查找依赖对象。依赖注入有三种方式:构造器注入、setter 注入和接口注入。
  • 容器管理:Spring 通过一个容器(Container)来管理 Bean 的生命周期和依赖关系。容器是一个抽象概念,它可以是一个接口或者一个类,用于提供 Bean 的创建、获取、销毁等操作。Spring 提供了两种类型的容器:BeanFactory 和 ApplicationContext。BeanFactory 是最基本的容器,它只提供了最简单的功能,如延迟加载、单例缓存等。ApplicationContext 是基于 BeanFactory 的扩展,它提供了更多的高级功能,如事件发布、资源加载、国际化等。

如何使用 Spring IOC 容器?

要使用 Spring IOC 容器,我们需要进行以下几个步骤:

  • 创建 Java 类,并添加相应的注解或者编写 XML 配置文件来定义 Bean 的信息。
  • 创建 Spring 容器,并加载配置文件或者扫描注解。
  • 从 Spring 容器中获取或者注入所需的 Bean,并使用它们完成业务逻辑。

下面我们来看一个简单的例子:

// 创建一个 User 类
public class User {private String name;private int age;// 省略构造器、getter 和 setter 方法public void sayHello() {System.out.println("Hello, I am " + name + ", I am " + age + " years old.");}
}// 创建一个 UserService 类
public class UserService {// 注入 User 类型的 Bean@Autowiredprivate User user;public void greetUser() {// 调用 User 的方法user.sayHello();}
}// 创建一个测试类
public class Test {public static void main(String[] args) {// 创建一个 ApplicationContext 类型的容器,并加载配置文件ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 从容器中获取 UserService 类型的 BeanUserService userService = context.getBean(UserService.class);// 调用 UserService 的方法userService.greetUser();}
}

在这个例子中,我们创建了两个 Java 类:User 和 UserService。User 类表示用户的实体类,UserService 类表示用户的业务类。我们在 UserService 类中使用 @Autowired 注解来注入 User 类型的 Bean,这样就可以在 UserService 中使用 User 的方法。

然后我们创建了一个测试类,在测试类中我们创建了一个 ApplicationContext 类型的容器,并加载了配置文件 applicationContext.xml。在配置文件中,我们定义了 User 和 UserService 两个 Bean 的信息,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 定义一个 User 类型的 Bean --><bean id="user" class="com.example.User"><!-- 设置 User 的属性 --><property name="name" value="Tom"/><property name="age" value="20"/></bean><!-- 定义一个 UserService 类型的 Bean --><bean id="userService" class="com.example.UserService"><!-- 注入 User 类型的 Bean --><property name="user" ref="user"/></bean></beans>

在配置文件中,我们使用 <bean> 标签来定义 Bean 的信息,如 id、class、property 等。我们可以通过 id 属性来指定 Bean 的唯一标识符,通过 class 属性来指定 Bean 的全限定类名,通过 property 标签来设置 Bean 的属性。我们可以通过 value 属性来指定属性的值,通过 ref 属性来指定属性的引用。在这个例子中,我们定义了 user 和 userService 两个 Bean,并且将 user Bean 注入到 userService Bean 中。

最后,我们在测试类中从容器中获取 userService 类型的 Bean,并调用其方法。运行测试类,我们可以看到输出结果如下:

Hello, I am Tom, I am 20 years old.

这说明我们成功地使用了 Spring IOC 容器来创建和管理对象,并实现了对象之间的依赖注入。

总结

本文为介绍了 Spring IOC 容器的原理和应用,更好掌握 Spring 的核心技术。Spring IOC 容器可以帮助我们实现对象之间的解耦,让对象的创建和管理由 Spring 容器来完成,而不是由对象自己或使用对象的类来完成。这样可以提高代码的可维护性和可扩展性,也可以方便地进行单元测试和依赖注入。

 

相关文章:

Spring IOC 容器:掌握 Spring 的核心技术

Spring 是一个非常流行和强大的 Java 开发框架&#xff0c;它可以帮助我们简化和优化 Java 项目的开发过程。Spring 的核心技术之一就是 IOC&#xff08;Inversion of Control&#xff0c;控制反转&#xff09;&#xff0c;它可以实现对象之间的解耦&#xff0c;让对象的创建和…...

python实现批量从excel列表显示图片网址中下载图片

遇到一个需求&#xff1a;给了一个excel表&#xff0c;里面有很多网址图片&#xff0c;要把图片下载到本地。手动操作的话就是在浏览器里输入网址&#xff0c;再图片另存为保存。这篇文章介绍一下使用python代码批量实现 第一步操作就是实现从网上下图片&#xff0c;这个用到了…...

java 单元测试Junit

所谓单元测试&#xff0c;就是针对最小的功能单元&#xff0c;编写测试代码对其进行正确性测试。为了测试更加方便&#xff0c;有一些第三方的公司或者组织提供了很好用的测试框架&#xff0c;给开发者使用。这里介绍一种Junit测试框架。Junit是第三方公司开源出来的&#xff0…...

Java中Timer和TimerTask的使用

这两个类使用起来非常方便&#xff0c;可以完成我们对定时器的绝大多数需求 Timer类是用来执行任务的类&#xff0c;它接受一个TimerTask做参数 Timer有两种执行任务的模式,最常用的是schedule,它可以以两种方式执行任务:1:在某个时间(Data)&#xff0c;2:在某个固定的时间之后…...

计算机竞赛 机器视觉 opencv 深度学习 驾驶人脸疲劳检测系统 -python

文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.2 打哈欠检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#x…...

DFS寻找从s到t的所有路径

问题描述&#xff1a; 输入一个有向图&#xff0c;输出从s到t的所有路径的结点 输入&#xff1a; 3 3 0 1 1 2 0 2输出&#xff1a; 0 1 2 0 2 代码&#xff1a; #include<bits/stdc.h> using namespace std;const int N 103; vector<int>e[N];//用行为N的…...

分享!JetBrains IDE中的GitLab支持

GitLab是流行的基于git的软件开发和部署平台之一&#xff0c;虽然很长一段时间以来&#xff0c;所有基本git操作都已经可以通过GitLab实现&#xff0c;但GitLab集成仍是JetBrains社区的一大最热门请求。为此&#xff0c;JetBrains团队今年与GitLab联手提供了这种类型的集成。 …...

jq弹窗拖动改变宽高

预览效果 <div classtishiMask><div class"tishiEm"><div id"coor"></div><div class"topNew ismove"><span class"ismove">提示</span><p onclick"closeTishi()"></p&…...

时间不确定度在分布式系统中的说明

On the one hand 时间不确定度问题和影响在分布式系统中 说明 时钟不确定度&#xff08;Clock Uncertainty&#xff09;是指在分布式系统中&#xff0c;由于网络延迟、时钟漂移等因素导致系统中各个节点时钟的不同步现象。这种不同步可能会影响到分布式系统的一致性和正确性…...

VMware vCenter 从6.7跨版本升级至7.0U3N

本文尝试使用 vCenter Server Appliance 管理界面 (VAMI) 进行对vCenter Server Appliance7应用进行小版本升级&#xff0c;从6.7.0.47000升级到7.0.3.01600&#xff08;7.0U3N&#xff09;。 一、升级前的准备工作 1、检查当前运行环境&#xff08;当前为6.7.0.47000&#x…...

大麦订单生成器最新版 大麦订单一键生成截图

1.可以一键添加&#xff0c;生成的假订单没有水印&#xff0c;界面也很真实。 2.在软件中输入生成的信息&#xff0c;这是产品信息&#xff0c;选择生成的产品图像&#xff0c;最后生成它。 后台一键生成&#xff0c;独立后台管理 教程&#xff1a;解压源码&#xff0c;修改数…...

如何对Map集合的key进行大小写转换?

工具类&#xff1a; ToUpperCaseKeyMapUtil.java public class ToUpperCaseKeyMapUtil {//对单一的mappublic static <T> Map<String, T> toUpperCaseKeyMap(Map<String, T> map) {if (map ! null) {List<String> mapKeyList new ArrayList<>…...

将函数实现放到CPP报“无法解析的外部符号...”,系VS Bug

发现一个现象&#xff0c;就是项目中有一个类&#xff0c;如果将函数实现全部放到头文件中&#xff0c;编译不报错&#xff0c;如果将函数实现放到CPP中则始终提示“无法解析的外部符号...”&#xff0c;考虑到放到头文件中能正常编译运行&#xff0c;显然这里不符合“无法解析…...

异步FIFO设计的仿真与综合技术(3)

概述 本文主体翻译自C. E. Cummings and S. Design, “Simulation and Synthesis Techniques for Asynchronous FIFO Design 一文&#xff0c;添加了笔者的个人理解与注释&#xff0c;文中蓝色部分为笔者注或意译。前文链接&#xff1a; 异步FIFO设计的仿真与综合技术&#xf…...

什么是区块链,解释区块链的原理和应用场景

1、什么是区块链&#xff0c;解释区块链的原理和应用场景。 区块链是一种分布式数据库&#xff0c;它由一系列按照时间顺序排列的数据块组成&#xff0c;并采用密码学方式保证不可篡改和不可伪造。区块链技术最初起源于比特币&#xff0c;作为比特币的底层技术&#xff0c;用于…...

使用bert进行文本二分类

构建BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;的训练网络可以使用PyTorch来实现。下面是一个简单的示例代码&#xff1a; import torch import torch.nn as nn from transformers import BertModel, BertTokenizer# Load BERT to…...

用Windows Installer CleanUp Utility 在windows server上面将软件卸载干净,比如SQLSERVER

这里写自定义目录标题 下载文件&#xff1a;Windows Installer CleanUp Utility。 通过以上工具可以将一个应用程序卸载干净。...

Java手写LinkedList和拓展

Java手写LinkedList和拓展 思维导图 #mermaid-svg-K0RTlFFvnikDRvqp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-K0RTlFFvnikDRvqp .error-icon{fill:#552222;}#mermaid-svg-K0RTlFFvnikDRvqp .error-text{fill…...

机器学习(14)---逻辑回归(含手写公式、推导过程和手写例题)

逻辑回归 一、逻辑回归概述二、模型、策略和优化&#xff08;手写&#xff09;三、w和b的梯度下降公式推导四、例题分析4.1 题目4.2 解答 一、逻辑回归概述 1. 逻辑回归也称作logistic回归分析&#xff0c;是一种广义的线性回归分析模型&#xff0c;属于机器学习中的监督学习。…...

LLFormer 论文阅读笔记

Ultra-High-Definition Low-Light Image Enhancement: A Benchmark and Transformer-Based Method 这是南京大学在AAAI 2023发表的一篇AAAI2023 超高清图像暗图增强的工作。提出了一个超高清暗图增强数据集&#xff0c;提供了4K和8K的图片&#xff0c;同时提出了一个可用于暗图…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...

五子棋测试用例

一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏&#xff0c;有着深厚的文化底蕴。通过将五子棋制作成网页游戏&#xff0c;可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家&#xff0c;都可以通过网页五子棋感受到东方棋类…...

SpringCloud优势

目录 完善的微服务支持 高可用性和容错性 灵活的配置管理 强大的服务网关 分布式追踪能力 丰富的社区生态 易于与其他技术栈集成 完善的微服务支持 Spring Cloud 提供了一整套工具和组件来支持微服务架构的开发,包括服务注册与发现、负载均衡、断路器、配置管理等功能…...

安宝特方案丨从依赖经验到数据驱动:AR套件重构特种装备装配与质检全流程

在高压电气装备、军工装备、石油测井仪器装备、计算存储服务器和机柜、核磁医疗装备、大型发动机组等特种装备生产型企业&#xff0c;其产品具有“小批量、多品种、人工装配、价值高”的特点。 生产管理中存在传统SOP文件内容缺失、SOP更新不及、装配严重依赖个人经验、产品装…...