浅谈Spring中的一些技术

一、前言

        在学习Spring或者SpringBoot原理时,心里要始终想着一件事情:只有把对象(也可以称之为组件、bean)放入到Spring的IOC容器中,才能使用Spring为我们提供的一系列强大功能。

二、一些说明

        在学习Spring或者SpringBoot的过程中,我们经常听到 <组件>、<bean>这两个词,那么这两个词指代什么呢?个人的一些浅显理解:你就把这两个词理解成普通的Java对象就可以,比如你自己写的一个User类(你创建一个User对象,把其添加到Spring的IOC容器中,这个User对象就可以称之为一个User组件,或者称之为一个bean组件),你创建了第三方的某个类的对象,然后把其放入Spring的IOC容器中,就可以这样说:我在容器中放入了某个类的一个组件。

三、添加组件(bean)到容器中

       如何把自己写的对象(或称之为组件,或称之为bean)或者第三方组件放入到IOC容器中呢?有四种方式:

3.1 包扫描 + 组件标注注解

        即在某个配置类(配置类指的是标注了@Configuration注解的类)上标注@ComponentScan(basePackages={"包名1","包名2"}), 然后再类上标注@Component、@Repository、@Service、@Controller等注解的方式。

        注意:此种方式局限于想要把自己写的类添加到IOC容器中。

3.2 @Bean

        在配置类中使用@Bean的方式给容器中导入一个组件。使用这种方式可以把第三方包中的组件导入到IOC容器中,让IOC容器帮我们管理第三方的组件,当需要使用第三方组件时,再从容器中获取就好了。

3.3 @Import

3.3.1 @Import导入普通组件

        @Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名。比如你创建了一个com.example.User类,使用@Import(value={User.class})就可以给容器中导入一个User组件。

3.3.2 @Import(value={xxxImportSelector.class})

        可以实现ImportSelector接口,然后实现接口中的 selectImports方法,让这个方法返回需要导入容器中的组件的全限定类名数组。然后使用 @Import(value = {MyImportSelector.class})的方式可以一次性给容器中导入多个组件。

3.3.3 @Import(value={xxxImportBeanDefinitionRegistrar.class})

        可以实现 ImportBeanDefinitionRegistrar 接口,然后实现接口中的 registerBeanDefinitions 方法,在方法的实现中手动注册 BeanDefinition 到IOC容器中。然后使用 @Import(value = {MyImportBeanDefinitionRegistrar.class})的方式给容器中导入组件。

3.4 使用FactoryBean

        使用Spring提供的 FactoryBean(工厂Bean):

         1)、默认获取到的是工厂bean调用getObject创建的对象

         2)、要获取工厂Bean本身,我们需要给id前面加一个&前缀

二、单例还是多例

        导入到容器中的组件,是单例还是多例呢?默认存放在Spring IOC容器中的组件都是单例的,当然我们也可以控制放入IOC容器中的组件是否单例还是多例。比如在使用 @Bean给容器中放入组件时,可以使用 @Scope(value = "singleton") 或者 @Scope(value = "prototype") 控制你要放入到IOC容器中的组件是否为单例。

三、Bean的生命周期

        把组件放入到IOC容器中,就意味着我们把一个对象交给了Spring 的IOC容器管理。每一个组件在IOC容器中都是有生命周期的。组件的生命周期概况起来有如下四个阶段:

bean的对象创建(调用bean的构造方法创建对象) -> 给bean进行属性赋值 -> 后置处理器的前置处理方法 -> 初始化 -> 后置处理器的后置处理方法 -> 销毁bean

bean对象创建,主要分为单实例bean的创建和多实例bean的创建:

1)单实例bean:在容器启动时创建所有的单实例bean;

2)多实例bean:在每次获取bean组件时,都会创建新的bean。

bean的属性赋值(见第四小节)

后置处理器的前置处理方法 -> 初始化 -> 后置处理器的后置处理方法 -> 销毁bean

针对bean的初始化前后,还可以做一些其他工作,有BeanPostProcessor来完成.

BeanPostProcessor.postProcessBeforeInitialization (在初始化方法执行之前进行后置处理工作
<调用初始化方法>
BeanPostProcessor.postProcessAfterInitialization  (在初始化方法执行之后进行后置处理工作
<销毁bean>

其中bean的初始化和销毁方式有如下几种:

(a) 通过@Bean注解指定 initMethod和destroyMethod 
(b) 让bean实现 InitializingBean 和 DisposableBean 接口
(c) JRS250提供的注解:
     @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
     @PreDestroy:在容器销毁bean之前通知我们进行清理工作 

四、属性赋值

        在给组件中的属性赋值时,我们可以使用@Value的方法,@Value可以写普通字符串,SpEL表达式,可以从配置文件中通过${xxx}的方式取值,需要把配置文件通过 @PropertySource引入进来,使配置文件中k/v键值对被Spring读取到运行时环境变量里面;

五、组件之间的依赖注入

        组件之间会有依赖关系,比如xxxService依赖xxxDao组件,可以Spring或Java规范为我们提供的组件注入功能,如@Autowired + @Qualifier指定要注入的组件,Java规范里面的@Resource和@Inject注解。

        疑问1:为什么标注了@Autowired注解之后,组件就自动给其属性进行了赋值呢?这就是组件注入的后置处理器(xxxPostProcessor)在底层进行工作。 

        疑问2:Spring在底层给IOC容器中注入了一些有用的组件,如果我们想把这些底层组件注入到我们自定义的组件中该怎么做呢?可以让自定义的组件实现Spring给我们提供的各种xxxAware接口,然后Spring在把我们自定义的组件添加到容器中的时候,会应用xxxAware对应的后置处理器,把其底层的组件注入到我们自定义的组件中。

        疑问3:我还想让一些组件在特定条件下才注入到容器中,而不是无脑往容器中注入,该怎么办呢?可以使用@Import的,指定自定义的实现了ImportSelector接口的类,在自定义的实现类中进行进行条件控制,从而控制是否要导入哪些组件,还可以通过指定@Condition注解,需要我们自己实现 Condition接口,在接口中判断是否要导入某些组件。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【python基础】—如何理解安装程序时要配置Widows和DOS操作系统中的path环境变量?

文章目录 前言一、环境变量是什么&#xff1f;二、为什么需要设置环境变量&#xff1f;三、配置anaconda的环境变量 前言 在安装一些程序的时候&#xff0c; 我们总是需要将安装路径配置到正在使用电脑的环境变量里。为什么要进行这一步呢&#xff1f;本文主要解释Widows和DOS…

c++ word转换为pdf

在windows系统下&#xff0c;使用QAxObject效果是最好的 转60多兆的文件速度还是可以的&#xff0c;不建议使用多线程&#xff0c;因为多线程会多次调用转换函数&#xff0c;导致程序一直运行&#xff0c;只有全部转换完成后&#xff0c;程序才能继续向下运行&#xff0c;但是c…

Cesium 二三维热力图

Cesium 二三维热力图 原理&#xff1a;主要依靠heatmap.js包来实现 效果图&#xff1a;

Java面试八股之MYISAM和INNODB有哪些不同

MYISAM和INNODB有哪些不同 MyISAM和InnoDB是MySQL数据库中两种不同的存储引擎&#xff0c;它们在设计哲学、功能特性和性能表现上存在显著差异。以下是一些关键的不同点&#xff1a; 事务支持&#xff1a; MyISAM 不支持事务&#xff0c;没有回滚或崩溃恢复的能力。 InnoDB…

关于在自行封装的组件库中(使用vue-class-component)使用Vue-i18n无法正常翻译的解决办法

文章目录 介绍背景现象1解决办法 现象2原因分析解决办法 最终方案 介绍 大家或多或少都用过别人封装的组件库&#xff0c;甚至有人或者公司内有自行封装的一些公用组件库&#xff0c;而国际化翻译现在已经是各大项目中必不可少的一个插件了&#xff0c;但组件库中使用 i18n 进…

文章解读与仿真程序复现思路——太阳能学报EI\CSCD\北大核心《绿电交易场景下计及温控负荷的高铁站两阶段调度策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

成人高考专升本专业有哪些?深职训学校帮您圆梦

成人高考专升本专业选择多样化 成人高考专升本考试是成人高考的一种考试形式&#xff0c;主要面向已经参加工作的人员&#xff0c;旨在选拔具有高等教育需求的成人考生&#xff0c;录取到高等学校继续深造。成人高考专升本考试的专业选择非常多样化&#xff0c;涵盖了人文社科…

Python酷库之旅-第三方库Pandas(006)

目录 一、用法精讲 10、pandas.DataFrame.to_excel函数 10-1、语法 10-2、参数 10-3、功能 10-4、返回值 10-5、说明 10-6、用法 10-6-1、数据准备 10-6-2、代码示例 10-6-3、结果输出 11、pandas.ExcelFile类 11-1、语法 11-2、参数 11-3、功能 11-4、返回值 …

RNN文献综述

循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一种专门用于处理序列数据的神经网络模型。它在自然语言处理、语音识别、时间序列预测等领域有着广泛的应用。本文将从RNN的历史发展、基本原理、应用场景以及最新研究进展等方面进行综述。 历…

大数据平台之数据同步

数据同步也成为CDC (Chanage Data Capture) 。Change Data Capture (CDC) 是一种用于跟踪和捕获数据库中数据变更的技术&#xff0c;它可以在数据发生变化时实时地将这些变更捕获并传递到下游系统。以下是一些常用的开源 CDC 方案&#xff1a; 1. Flink CDC Flink CDC 是基于 …

Linux——目录结构

基本介绍 Linux的文件系统是采用级层式的树状目录结构&#xff0c;在此结构中的最上层是根目录"/"&#xff0c;然后在根目录下再创建其他的目录 在Linux中&#xff0c;有一句经典的话&#xff1a;在Linux世界里&#xff0c;一切皆文件 Linux中根目录下的目录 具体的…

案例精选 | 聚铭网络助力南京市玄武区教育局构建内网日志审计合规体系

南京市玄武区教育局作为江苏省教育领域的先锋机构&#xff0c;其工作重点涵盖了教育政策的实施、教育现代化与信息化的融合、教育资源的优化、教育质量的提升以及教育公平的促进。在这一背景下&#xff0c;网络安全管理成为了确保教育信息化顺利推进的关键环节之一。 根据玄武…

二进制求和、字符串相加-sting类题型

67. 二进制求和 - 力扣&#xff08;LeetCode&#xff09; 两个题目方法完全一样 用两个数据的末尾位相加&#xff0c;从末尾位开始逐位相加&#xff0c;记录进位&#xff1b; class Solution { public:string addBinary(string a, string b) {int end1 a.size() - 1;int end…

【Qwen2部署实战】Ollama上的Qwen2-7B:一键部署大型语言模型指南

系列篇章&#x1f4a5; No.文章1【Qwen部署实战】探索Qwen-7B-Chat&#xff1a;阿里云大型语言模型的对话实践2【Qwen2部署实战】Qwen2初体验&#xff1a;用Transformers打造智能聊天机器人3【Qwen2部署实战】探索Qwen2-7B&#xff1a;通过FastApi框架实现API的部署与调用4【Q…

做有一个有表情且会动的 Finder

作为一只合格的互联网巡回猎犬&#xff0c;今天给大家分享一个有趣且无聊的小工具&#xff0c;摸鱼发呆必备&#xff0c;可以说是一件「无用良品」了。 软件介绍 Mouse Finder 长的跟访达差不多&#xff0c;功能也一样&#xff0c;但有一个重要区别&#xff1a;眼睛会跟随鼠标…

YOLOv8数据集可视化[目标检测实践篇]

先贴代码,后面再补充解析。 这个篇章主要是对标注好的标签进行可视化,虽然比较简单,但是可以从可视化代码中学习到YOLOv8是如何对标签进行解析的。 下面直接贴代码: import cv2 import numpy as np import osdef read_det_labels(label_file_path):with open(labe…

DAY20-力扣刷题

1.填充每个节点的下一个右侧节点指针 116. 填充每个节点的下一个右侧节点指针 - 力扣&#xff08;LeetCode&#xff09; 方法一&#xff1a;层次遍历 class Solution {public Node connect(Node root) {if (root null) {return root;}// 初始化队列同时将第一层节点加入队列…

动手学深度学习(Pytorch版)代码实践 -循环神经网络-51序列模型

51序列模型 import torch from torch import nn from d2l import torch as d2l import matplotlib.pyplot as pltT 1000 # 总共产生1000个点 time torch.arange(1, T 1, dtypetorch.float32) x torch.sin(0.01 * time) torch.normal(mean0, std0.2, size(T,)) d2l.plot(…

【IT领域新生必看】Java编程中的神奇对比:深入理解`equals`与`==`的区别

文章目录 引言什么是操作符&#xff1f;基本数据类型的比较示例&#xff1a; 引用类型的比较示例&#xff1a; 什么是equals方法&#xff1f;equals方法的默认实现示例&#xff1a; 重写equals方法示例&#xff1a; equals与的区别比较内容不同示例&#xff1a; 使用场景不同示…

CSS position属性之relative和absolute

目录 1 参考文章2 五个属性值3 position:static4 position:relative&#xff08;相对&#xff09;5 position:absolute&#xff08;绝对&#xff09; 1 参考文章 https://blog.csdn.net/lalala_dxf/article/details/123566909 https://blog.csdn.net/WangMinGirl/article/deta…