Spring IoCDI(2)
IoC详解
通过上面的案例, 我们已经知道了IoC和DI的基本操作, 接下来我们来系统地学习Spring IoC和DI的操作.
前面我们提到的IoC控制反转, 就是将对象的控制权交给Spring的IoC容器, 由IoC容器创建及管理对象. (也就是Bean的存储).
Bean的存储
我们之前只讲到了@Component注解来使得对象交给IoC容器管理. 而Spring为了更好地管理Web应用程序, 提供了更丰富的注解.
当前有两类注解:
1.类注解@Controller(控制器存储), @Service(服务存储), @Reposity(仓库), @Component(组件), @Configuration(配置)
2.方法注解: @Bean
类注解的使用
由于这里五个类注解在功能上基本是一致的, 所以这里用@Controller进行介绍.
使用@Controller存储bean的代码如下所示:
@Controller //将对象存储到Spring中
public class MyController {public void sayHi() {System.out.println("Hi, UserController...");}
}
如何观察这个对象已经存在Spring容器当中了呢?
接下来我们学习如何从Spring容器中获取对象.
@SpringBootApplication
public class SpringbootDemoApplication {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringbootDemoApplication.class);//从Spring上下文中获取对象MyController myController = context.getBean(MyController.class);//获取对象myController.sayHi();}
}
ApplicationContext 翻译过来就是: Spring上下文.
因为对象交给Spring管理, 所以获取对象要从Spring中获取, 那么就得先得到Spring的上下文.
关于上下文的概念
在计算机领域, 上下文这个概念, 我们之前在在进程PCB核心属性讲过, 它是指支持进程调度的重要属性. 等下次调度回CPU时,会把寄存器上的回复回来.
这里的上下文, 就是指当前的运行环境, 也可以看作是一个容器, 容器里存很多内容, 这些内容是当前运行的环境.
观察运行结果, 发现成功从Spring中获取到Controller对象, 并执行Controller的SayHi方法.

获取bean对象的其他方式
上述代码是根据类型来查找对象, 如果Spring容器中, 同一个类型存在多个bean的话, 怎么获取呢?
ApplicationContext也提供了其它获取bean的方式, ApplicationContext获取bean对象的功能, 是父类BeanFactory提供的功能.

可以发现, 我们获取bean共有五种方法, 而常用的是第1, 2, 4三种. 第一种是根据名称获取bean对象, 第二种是通过名称, 类型获取bean对象. 第三种是通过类型获取对象.
其中1,2种都涉及根据名称来获取对象, bean的名称是什么呢?
Spring bean是Spring框架在运行时管理的对象, Spring会给管理的对象起一个名字.
比如学校管理学生, 会给每个学生分配一个学号, 根据学号, 可以找到对应学生.
Spring也是如此, 给每个对象起一个名字, 根据Bean名称(BeanId)就可以获取到对应对象.
Bean命名约定
程序开发人员不需要为bean指定名称(BeanId), 如果没有显式提供名称(BeanId), Spring容器将为该bean生成唯一的名称.
命名约定使用Java标准约定作为实例字段名, 也就是说bean名称以小写字母开头, 然后使用驼峰时大小写.
eg. MyController -> myController
也有一些特殊情况, 当有多个字符且第一个和第二个字符都大写时, 将保留原始的大小写.
eg. UController -> UController
根据这个规则, 我们来获取Bean.
@SpringBootApplication
public class SpringbootDemoApplication {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringbootDemoApplication.class);//根据bean类型, 从Spring上下文中获取对象.MyController myController1 = context.getBean(MyController.class);//根据bean名称, 从Spring上下文中获取对象MyController myController2 = (MyController) context.getBean("myController");//根据bean名称+对象, 从Spring上下文中获取对象MyController myController3 = context.getBean("myController", MyController.class);//使用对象System.out.println(myController1);System.out.println(myController2);System.out.println(myController3);}
}
运行结果:

地址一样, 说明对象是一个.
获取bean对象, 是父类BeanFactory提供的功能.
ApplicationContext VS BeanFactory (面试题)
继承关系和功能来说: Spring有两个顶级的接口: ApplicationContext 和BeanFactory. 其中
BeanFactory提供了基础的访问容器的能力, 而Application属于BeanFactory的子类. 它除了继承BeanFactory的所有功能之外, 还有独特的特性: 对国际化的支持, 资源访问支持, 以及事件传播方面的支持.
从性能来说: ApplicationContext是一次性加载并初始化的所有Bean对象(可类似于饿汉模式),BeanFactory是需要哪个再去加载哪个, 因此更加轻量.(空间换时间) (一般建议用ApplicationContext, 因为现在机器的性能更高了).
为什么要这么多类注解?
这个也是和前面讲的应用分层相呼应. 让程序员看到注解之后, 就能知道这个类的用途.
@Controller: 控制层, 接收请求, 对请求进行处理, 并进行响应.
@Service: 业务逻辑层,处理具体的逻辑.
@Respository: 数据访问层, 也称为持久层. 负责数据的访问操作.
@Configuration: 配置层. 处理项目中的一些配置信息.
这个就类似于车牌号的功能, 一看开头, 不管后面的字符串是什么, 就能知道这个车是哪里的.
程序的应用分层, 调用逻辑如下:

类注解之间的关系
查看@Controller, @Configuration, @Repository, @Service的源码发现:
这些注解中其实都有一个元注解: @Component, 说明它们本身就属于@Component的"子类", 说明它们本身就是属于@Component的"子类". @Component是一个元注解, 也就是说可以注解其它类注解, 如@Controller, @Service, @Repository, 这些注解都可以说是@Component的衍生注解.
方法注解@Bean
类注解是添加到某个类上的, 但是存在两个问题:
1.使用外部包里的类, 没办法添加类注解
2.一个类, 需要多个对象, 比如多个数据源.
这种场景, 我们就需要注解@Bean
方法注解需要配合类注解使用
在Spring框架的设计中, 方法注解@Bean要配合类注解才能将对象正常地存储到Spring容器中.
举个栗子:
@Component
public class BeanConfig {@Beanpublic User user() {User user = new User();user.setName("lisi");user.setAge(20);return user;}
}
运行下述代码:
@SpringBootApplication
public class SpringbootDemoApplication {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringbootDemoApplication.class);User user = context.getBean(User.class);System.out.println(user);}
}
得到运行结果:

定义多个对象
对于同一个类, 如何定义多个对象呢?
比如多数据源的场景, 类是同一个, 但是配置不同, 指向不同的数据源.
我们看下@Bean的使用
@Component
public class BeanConfig {@Beanpublic User user1() {User user = new User();user.setName("lisi");user.setAge(20);return user;}@Beanpublic User user2() {User user = new User();user.setName("zhangsan");user.setAge(18);return user;}
}
当定义到多个对象时, 我们继续使用上面的代码, 能获取到什么对象? 我们来运行一下:

报错信息显示:期望只有一个匹配, 结果却发现了两个: user1, user2.
从报错信息中, 可以看出来, @Bean注解的bean, bean名称就是它的方法名.
接下来以正确的方式来获取Bean对象.
@SpringBootApplication
public class SpringbootDemoApplication {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringbootDemoApplication.class);User user1 = (User) context.getBean("user1");User user2 = (User) context.getBean("user2");System.out.println(user1);System.out.println(user2);}
}
运行结果:

可以看到, @Bean针对同一个类, 定义多个对象.
重命名Bean
@Bean(name = {"u1", "user1"})
添加类似的注解仍可以运行成功, 这是将user1重命名为u1的一种方式. 类似地, 还有如下方式:
@Bean({"u1", "user1"})
//只有一个名称时, 其它的内容可以省略.
@Bean("u1")
扫描路径
使用前面注解声明的bean, 一定会生效吗?
不一定(原因: bean想要生效, 还需要被Spring扫描).
当在同一个包内, 可以直接被Spring扫描到, 如果不在同一个包, 就可以通过@ComponentScan来配置扫描路径.
@ComponentScan({"com.example.demo"})
@SpringBootApplication
public class SpringIocDemoApplication {public static void main(String[] args) {//获取Spring上下⽂对象ApplicationContext context = SpringApplication.run(SpringIocDemoApplication.class);//从Spring上下⽂中获取对象User u1 = (User) context.getBean("u1");//使⽤对象System.out.println(u1);}
}
{}里可以配置多个包路径.
这种做法仅作了解, 不做推荐使用.
相关文章:
Spring IoCDI(2)
IoC详解 通过上面的案例, 我们已经知道了IoC和DI的基本操作, 接下来我们来系统地学习Spring IoC和DI的操作. 前面我们提到的IoC控制反转, 就是将对象的控制权交给Spring的IoC容器, 由IoC容器创建及管理对象. (也就是Bean的存储). Bean的存储 我们之前只讲到了Component注解…...
30. UE5 RPG GamplayAbility的配置项
在上一篇文章,我们介绍了如何将GA应用到角色身上的,接下来这篇文章,将主要介绍一下GA的相关配置项。 在这之前,再多一嘴,你要能激活技能,首先要先应用到ASC上面,才能够被激活。 标签 之前介绍…...
提升自己最快的方式是什么?
提升自己最快的方式通常涉及到个人成长的各个方面,包括心理、情感、技能和知识等。根据查阅到的资料,以下是一些具体的方法和步骤,帮助你快速提升自己: 1. 培养屏蔽力 荷兰畅销书作家罗伊马丁纳提到,屏蔽力是个人成长…...
题目:一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
题目:一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。 There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence…...
《HelloGitHub》第 96 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 https://github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 …...
C++tuple类型
tuple 类型 tuple是类似pair的模板。 每个pair的成员类型都不相同,但每个pair都恰好有两个成员。不同tuple类型的成员类型也不相同,但一个tuple可以有任意数量的成员。 每个确定的tuple类型的成员数目是固定的,但一个tuple类型的成员数目可…...
亚远景科技-浅谈ASPICE标准和ASPICE认证/评估
ASPICE(Automotive SPICE)是一种针对汽车行业的软件开发过程的评估模型,它旨在帮助汽车制造商和供应商提高软件开发过程的能力和质量,从而提升产品的质量、安全性和效率。 ASPICE标准涵盖了软件开发的各个阶段和活动,…...
PHP性能提升方案
一、背景与介绍 PHP语言开发效率高,特别应用于适合中小型项目,对于创业初期敏捷开发验证项目可行性或者Demo演示绝对占据优势。 但是随着现在Web应用的复杂性,针对项目要适应高并发、高流量的访问特性,PHP确实在性能方面相对Go、J…...
关系(二)利用python绘制热图
关系(二)利用python绘制热图 热图 (Heatmap)简介 热图适用于显示多个变量之间的差异,通过颜色判断彼此之间是否存在相关性。 快速绘制 基于seaborn import seaborn as sns import pandas as pd import numpy as np i…...
P8597 [蓝桥杯 2013 省 B] 翻硬币
# [蓝桥杯 2013 省 B] 翻硬币 ## 题目背景 小明正在玩一个“翻硬币”的游戏。 ## 题目描述 桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零),比如可能情形是 **oo***oooo&#x…...
主流公链 - Fantom
Fantom:高性能的区块链协议 Fantom是一种开创性的区块链协议,旨在革新去中心化应用和数字金融领域 技术特点 共识机制 Lachesis协议:Fantom使用了Lachesis协议作为其共识算法。Lachesis是一种 异步拜占庭容错(ABFT)共…...
vue-quill-editor 富文本编辑器(可上传视频图片),组件挂载的方式实现
1.安装 npm install vue-quill-editor --save npm install quill-image-drop-module --save npm install quill-image-resize-module --save2.在组件下面新增组件 QlEditor (1)index.vue <template><div><div idquillEditorQiniu><!-- 基于element…...
入门编程第一步,从记住这些单词开始
** 入门编程第一步,从记住这些单词开始 ** 2023-10-18 一、交互式环境与 print 输出 1、print : 打印/输出 2、coding : 编码 3、syntax : 语法 4、error : 错误 5、invalid : 无效 6、idenfifier : 名称/标识符 7、character : 字符 二、字符串的操作&#x…...
[C++]使用OpenCV去除面积较小的连通域
这是后期补充的部分,和前期的代码不太一样 效果图 源代码 //测试 void CCutImageVS2013Dlg::OnBnClickedTestButton1() {vector<vector<Point> > contours; //轮廓数组vector<Point2d> centers; //轮廓质心坐标 vector<vector<Point&…...
vscode连接不上,终端ssh正常,一直输入密码正确但是无法登录
若是之前链结果突然等不上,使用第一个链接 若是第一次链接连不上,先使用第二个链接,在使用第一个链接 原因:原因是服务器端的wget命令不能使用,vscode需要服务器端下载个文件,无法下载就导致了如上的错误…...
Hive on Spark 配置
目录 1 Hive 引擎简介2 Hive on Spark 配置2.1 在 Hive 所在节点部署 Spark2.2 在hive中创建spark配置文件2.3 向 HDFS上传Spark纯净版 jar 包2.4 修改hive-site.xml文件2.5 Hive on Spark测试2.6 报错 1 Hive 引擎简介 Hive引擎包括:MR(默认)…...
ROS 基本
ROS创建自己的功能包 ROS中工作空间(workspace)是一个存放工程开发相关文件的文件夹,其中有四个文件夹。 src:代码空间(Source Space)build:编译空间(Build Space)devel:开发空间(Development Space)install:安装空间(Install Space) OK接下来创作工作空间&#…...
Pygame基础9-射击
简介 玩家用鼠标控制飞机(白色方块)移动,按下鼠标后,玩家所在位置出现子弹,子弹匀速向右飞行。 代码 没有什么新的东西,使用两个精灵类表示玩家和子弹。 有一个细节需要注意,当子弹飞出屏幕…...
Ps:颜色查找
颜色查找 Color Lookup命令通过应用预设的 LUT 来改变图像的色彩和调性,从而为摄影师和设计师提供了一种快速实现复杂色彩调整的方法,广泛应用于颜色分级、视觉风格的统一和创意色彩效果的制作。 Ps菜单:图像/调整/颜色查找 Adjustments/Colo…...
vue3+vite 模板vue3-element-admin框架如何关闭当前页面跳转 tabs
使用模版: 有来开源组织 / vue3-element-admin 需要关闭的.vue 页面增加以下方法 //setup 里import {LocationQuery, useRoute, useRouter} from "vue-router"; const router useRouter(); function close() {console.log(|--router.currentRoute.value, router.cur…...
利用示波器直方图功能低成本测量信号抖动的方法与实践
1. 项目概述:用直方图低成本测量抖动在嵌入式系统、高速数字接口乃至电机控制的设计与调试中,信号抖动(Jitter)的测量和分析是一个绕不开的坎。无论是为了确保通信链路的误码率,还是为了验证时钟信号的纯净度ÿ…...
淘金币自动化脚本:3分钟完成淘宝全任务,每天节省20分钟
淘金币自动化脚本:3分钟完成淘宝全任务,每天节省20分钟 【免费下载链接】taojinbi 淘宝淘金币自动执行脚本,包含蚂蚁森林收取能量,芭芭农场全任务,解放你的双手 项目地址: https://gitcode.com/gh_mirrors/ta/taojin…...
如何做谷歌SEO排名优化?搞定高质量外链的4种高成功率技巧
很多刚接触谷歌SEO的朋友发现,自己的网站内容写了不少,可排名始终在搜索结果的五六页开外晃悠。排除掉网站技术层面的小毛病,最让大家头疼的往往就是外链。你可以把外链看作是其他网站给你的“信任投票”,如果投给你的都是些街边的…...
CipherChat:基于词元替换的端到端加密大模型对话方案解析
1. 项目概述:当大模型对话遇上密码学最近在折腾大语言模型(LLM)应用开发的朋友,可能都遇到过同一个头疼的问题:如何保证用户和模型之间对话的隐私和安全?我们辛辛苦苦搭建的智能客服、个人助理或者创意写作…...
macOS虚拟机解锁终极指南:在普通PC上运行苹果系统的完整解决方案
macOS虚拟机解锁终极指南:在普通PC上运行苹果系统的完整解决方案 【免费下载链接】unlocker VMware Workstation macOS 项目地址: https://gitcode.com/gh_mirrors/unlo/unlocker 想要在Windows或Linux电脑上体验macOS系统,但又不想花费高昂的价…...
Dify实战指南:从零构建大模型应用与智能体开发全流程
1. 项目概述:从零到一,构建你的大模型应用开发实战手册如果你对AI应用开发感兴趣,但又觉得从零开始搭建一个能用的智能体(Agent)或者知识库问答系统门槛太高,那么你很可能已经听说过Dify这个名字。作为一个…...
终极指南:MobileAgent如何用AI智能体彻底改变跨平台自动化体验
终极指南:MobileAgent如何用AI智能体彻底改变跨平台自动化体验 【免费下载链接】MobileAgent Mobile-Agent: The Powerful GUI Agent Family 项目地址: https://gitcode.com/GitHub_Trending/mo/mobileagent 你是否曾经想过,如果有一个AI助手能够…...
【独家首发】DeepSeek-VL与R1在HumanEval上的性能断层:87.3 vs 62.1分,这15.2分差距究竟卡在哪一行代码?
更多请点击: https://intelliparadigm.com 第一章:DeepSeek-VL与R1在HumanEval上的性能断层现象 HumanEval 是评估代码生成模型逻辑正确性的黄金基准,其测试集由 164 道手写 Python 编程题构成,每题包含函数签名、文档字符串和若…...
后端程序员必看:3-6个月从0到1转型高薪AI应用
本文针对传统后端程序员想转型AI应用开发的焦虑,提出了一条省时、高薪、稳定的转型路线。文章指出,转型AI应用开发的核心是复用后端优势,走“后端AI集成”的复合型路线,而非死磕底层算法。文章详细规划了3-6个月的转型路线&#x…...
惠来海康医院眼科母亲节:愿岁月温柔,护她眼底有光
惠来海康医院眼科母亲节:愿岁月温柔,护她眼底有光五月浅夏,暖意氤氲,当康乃馨的芬芳漫过街巷,母亲节便载着满心敬意如期而至。母亲,是岁月里最温柔的守望者,用一双眼眸,藏下对我们所…...
