SpringBoot中对Bean的处理方法以及第三方Bean处理的方式

news2024/11/23 16:35:05

我们可以通过Spring当中提供的注解@Component以及它的三个衍生注解(@Controller、@Service、@Repository)来声明IOC容器中的bean对象,为应用程序注入运行时所需要依赖的bean对象,也就是依赖注入DI。

关于IOC容器中Bean的其他使用细节,主要包括以下三方面:

  1. 获取IOC中的Bean
  2. 通过注解声明时的一些细节
  3. 第三Bean的创建

1. 如何从IOC容器中手动的获取到bean对象

这里就不谈DI的方式了哈

SpringBoot项目在启动的时候会自动的创建IOC容器(也称为Spring容器),并且在启动的过程当中会自动的将bean对象都创建好,存放在IOC容器当中。应用程序在运行时需要依赖什么bean对象,就直接进行依赖注入就可以了。

而在Spring容器中提供了一些方法,可以主动从IOC容器中获取到bean对象,下面介绍3种常用方式:

  1. 根据name获取bean 容器中默认为当前类的首字母小写

    Object getBean(String name)
    
  2. 根据类型获取bean

    <T> T getBean(Class<T> requiredType)
    
  3. 根据name获取bean(带类型转换)

    <T> T getBean(String name, Class<T> requiredType)
    

如果知道Spring注入的方式其实也就对应着在DI时,即依赖注入时的两种方式及按照名称,按照类型,还有当有多个实现类时,如果区分。

下面就通过代码来获取以及查看容器中的bean

定义一个父接口:

public interface FatherInterface {
    void hello();
}

定义一个实现类,实现父接口;注意加上@Component注解,表示这个类让Spring管理

@Component
public class SonComponent implements FatherInterface{
    @Override
    public void hello() {
        System.out.println("There is son");
    }
}

然后在测试类中注入容器对象,从容器中通过上面的三个方法获取bean

@SpringBootTest(classes = SkyApplication.class) // 这里因为我当前的项目是多模块所以需要指定一下
public class MyTestDemo {

    // 这个对象就是Springioc容器对象
    @Autowired
    private ApplicationContext application;

    @Test
    public void testGetBean(){
        // 方式一 根据name获取bean
        FatherInterface bean1 = (FatherInterface)application.getBean("sonComponent");
        System.out.println(bean1);
		// 方式二 根据类型获取bean
        FatherInterface bean2 = application.getBean(FatherInterface.class);
        System.out.println(bean2);
        // 方式三 根据name获取bean(带类型转换)
        FatherInterface bean3 = application.getBean("sonComponent",FatherInterface.class);
        System.out.println(bean3);
    }
}

控制台可见三种方式都可以获得到当前对象,并且当前地址相同

在这里插入图片描述

第三种存在的意义在于当使用第二种方式来获取的时候如果接口有两个实现类时,通过名字来区分。

比如现在:一个接口,两个实现类,如果再通过第二种方式获取就会出现异常,因为当按照类型查找时有两个Spring并不知道是哪个

在这里插入图片描述

报错主要信息如下:

available: expected single matching bean but found 2:

此时就需要通过名字来指定。

在Spring中我们也可以通过图形化界面来查看容器中的内容,其中高亮的是Spring所依赖的文件,其他的是第三方或我们自己编写bean。

在这里插入图片描述

在Spring中也提供了另一种方式通过在子类中使用**@Primary**,来指定当有通过类型获取的时候当有多个实现类时使用哪一个。

2. bean的作用域配置

通过上面我们可以看到不管通过哪一种方式得到的地址都是相同的,也就是单例。可见Spring默认创建的对象都是单例模式。

单例: 指的是在运行环境中一个类:只存在一个对象
spring 默认就是单例

@Scope 表示 作用范围
singleton 单例: 程序运行时只会创建一个对象
1) spring 启动时 就初始化
2) 想要使用时才初始化 应该加 @Lazy
prototype 多例: 每获取一次对象,都创建一个新的
使用时才初始化

在这里插入图片描述

写上的话提示:冗余默认参数值分配 即默认。

在Spring中支持五种作用域,后三种在web环境才生效:主要记忆前两种,一个单例一个多例。

作用域说明
singleton容器内同名称的bean只有一个实例(单例)(默认)
prototype每次使用该bean时会创建新的实例(非单例)
request每个请求范围内会创建新的实例(web环境中,了解)
session每个会话范围内会创建新的实例(web环境中,了解)
application每个应用范围内会创建新的实例(web环境中,了解)

把当前类的的@Scope注解的value修改为prototype

@Component
@Slf4j
@Scope(value ="prototype")
public class SonComponent implements FatherInterface{
    ....
}

此时再运行查看控制台当前就是多例,而对于创建时机,单例默认是Spring容器初始化时,可以通过@Lazy来指定

3. 管理第三方的bean对象

之前我们所配置的bean,像controller、service,dao三层体系下编写的类,这些类都是我们在项目当中自己定义的类(自定义类)。当我们要声明这些bean,也非常简单,我们只需要在类上加上@Component以及它的这三个衍生注解(@Controller、@Service、@Repository),就可以来声明这个bean对象了。
但是在我们项目开发当中,还有一种情况就是这个类它不是我们自己编写的,而是我们引入的第三方依赖当中提供的。

比如我们要使用dom4j 对xml文件进行解析的时候。因为dom4j就是第三方组织提供的。 dom4j中的SAXReader类就是第三方编写的。

按照我们之前的做法,需要在SAXReader类上添加一个注解@Component(将当前类交给IOC容器管理)

但是第三方提供的类是只读的。无法在第三方类上添加@Component注解或衍生注解。

那么我们应该怎样使用并定义第三方的bean呢?

  • 如果要管理的bean对象来自于第三方(不是自定义的),是无法用@Component 及衍生注解声明bean的,就需要用到**@Bean**注解。

解决方案1:在启动类上添加@Bean标识的方法

@SpringBootApplication
public class SpringbootWebConfig2Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebConfig2Application.class, args);
    }

    //声明第三方bean
    @Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器bean
    public SAXReader saxReader(){
        return new SAXReader();
    }
}

您可能会问,同样是new ,我使用的时候不使用注入使用new不好吗? 不好,如果当多次使用的时候每次都是新的对象,这样不便于管理。我们使用IOC的规则就是将对象,统一交给Spring容器(IOC容器)统一管理。

此时容器中就有了SAXReader对象,但在容器中的对象的名字是方法名

说明:以上在启动类中声明第三方Bean的作法,不建议使用(项目中要保证启动类的纯粹性)

解决方案2:在配置类中定义@Bean标识的方法

既然要保证启动类的纯粹性那么我们就创建一个配置类,专为第三方类服务。

@Configuration //配置类  (在配置类当中对第三方bean进行集中的配置管理)
public class CommonConfig {

    //声明第三方bean
    @Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器bean
          //通过@Bean注解的name/value属性指定bean名称, 如果未指定, 默认是方法名
    public SAXReader reader(DeptService deptService){
        System.out.println(deptService);
        return new SAXReader();
    }
}

如下:

在方法上加上一个@Bean注解,Spring 容器在启动的时候,它会自动的调用这个方法,并将方法的返回值声明为Spring容器当中的Bean对象。

注意事项 :

  • 通过@Bean注解的name或value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名。

  • 如果第三方bean需要依赖其它bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配。

关于Bean大家只需要保持一个原则:

  • 如果是在项目当中我们自己定义的类,想将这些类交给IOC容器管理,我们直接使用@Component以及它的衍生注解来声明就可以。
  • 如果这个类它不是我们自己定义的,而是引入的第三方依赖当中提供的类,而且我们还想将这个类交给IOC容器管理。此时我们就需要在配置类中定义一个方法,在方法上加上一个@Bean注解,通过这种方式来声明第三方的bean对象。

既然说到了这里那么关于声明Bean时的几个条件注解是少不了的,也就是通过注解,来告诉Spring我们在什么条件下才去创建这个Bean。即按照条件装配。在另一个笔记中:


@Conditional四个较常用的派生注解总结

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

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

相关文章

矿泉水为什么会溴酸盐超标

矿泉水为什么会溴酸盐超标&#xff1f; 水生产企业多使用臭氧消毒&#xff0c;不过&#xff0c;水生产企业不存在水运输路途遥远的问题&#xff0c;因此可以使用臭氧消毒。同时&#xff0c;也是因为臭氧在消毒后会直接变成氧气&#xff0c;所以不会有使用氯消毒后的那种味道&a…

give_you_flag(GIF原理、二维码定位符)

下载附件是一个GIF 看到最后你会发现它突然漏了一个二维码出来 我们将这个GIF分解成图片&#xff08;动图就是由多张静态图片组合而成&#xff0c;按照一定的顺序和时间播放的&#xff09; https://tu.sioe.cn/gj/fenjie/ 提取出里面包含二维码的那张 但是我们发现这里有一个…

word2vec原理

1.背景 2013年&#xff0c;Google开源了一款用于词向量计算的工具—word2vec&#xff0c;引起了工业界和学术界的关注。首先&#xff0c;word2vec可以在百万数量级的词典和上亿的数据集上进行高效地训练&#xff1b;其次&#xff0c;该工具得到的训练结果——词向量(word embed…

GDPU C语言 天码行空7

1. 数组最大值交换 ⭐ 1e9&#xff1a;10的9次方 #include<stdio.h>int main() {int n, i,idx 0;//idx 记录第一个出现的最大值下标scanf("%d", &n);double a[30];double max -1e9;// 1e9 表示10的9次方&#xff0c;十亿&#xff0c;int 的最大范围级别…

使用RT-Thread Studio搭配STM32CubeMX新建RT-Thread项目

STM32CubeMX下载 RT-Thread Studio下载 安装好RT-Thread Studio后&#xff0c;先打开RT-Thread SDK管理器确认有没有自己MCU需要的SDK包&#xff0c;直接安装好之后里面是有STM32F1系列的SDK包&#xff0c;其他的需要自己安装。 之后点击文件→新建→RT-Thread项目&#xff0…

C++ 实现 matlab 的 zp2tf 函数

文章目录1. matlab 的 zp2tf 函数的作用2. matlab 的 zp2tf 函数的使用方法3. C实现3.1 complex.h 文件3.2 zp2tf.h 文件4. 测试结果4.1 测试文件4.2 测试结果1. matlab 的 zp2tf 函数的作用 作用是将极点形式的 H(s) 函数的分母展开 2. matlab 的 zp2tf 函数的使用方法 [z,…

ICASSP2023 | 基于多任务学习的保留背景音的语音转换

在影视、有声书内容中&#xff0c;背景音是一种表现丰富的艺术形式。语音转换&#xff08;Voice Conversion&#xff09;如能将源说话人语音转换成目标说话人语音的同时&#xff0c;保留源语音中的背景音&#xff0c;将会提供更沉浸的语音转换体验。之前的语音转换研究主要关注…

低代码平台很赞,用2个小时,搭出1套应用

最近低代码很火&#xff0c;到处都是低代码的尝试贴&#xff0c;笔者今天也决定深入体验一下&#xff0c;感受它的便捷程度。 在案例开始之前&#xff0c;我们先来聊聊概念。 一、低代码 低代码实质上并不是一个新颖的话题&#xff0c;也不是最近才有的技术突破和创新&#xf…

Python--异常处理机制

Python异常处理机制 1、什么是异常处理&#xff1a; 程序运行时常会碰到一些错误&#xff0c;例如除数为 0、年龄为负数、数组下标越界等&#xff0c;这些错误如果不能发现并加以处理&#xff0c;很可能会导致程序崩溃。 可以简单的理解异常处理机制&#xff0c;就是在程序运…

Nginx生产环境配置、elasticsearch生产环境配置、rocketmq生产环境配置 (史上最全)

Nginx实现10万并发 在优化内核时&#xff0c;可以做的事情很多&#xff0c;不过&#xff0c;我们通常会根据业务特点来进行调整&#xff0c;当Nginx作为静态web内容服务器、反向代理或者提供压缩服务器的服务器时&#xff0c;期内核参数的调整都是不同的&#xff0c; 概述&am…

计算机组成原理——第五章中央处理器

半生风雨半生伤&#xff0c;半醉半醒半心凉 文章目录前言5.1 CPU的功能和基本结构5.2 指令周期的数据流5.3.1 单总线结构5.3.2 专用通路结构前言 之前我们就说过CPU主要包括两个部分&#xff0c;运算器和控制器&#xff0c;运算器主要是实现算数运算.逻辑运算&#xff0c; 运算…

React 搜索时遇到的坑

一、业务场景&#xff1a; 最近在优化React的天枢项目里面&#xff0c;搜索时遇到了一些问题。为了大家后面遇到和我一样的问题&#xff0c;给大家分享一下 二、问题描述&#xff1a; 1.点击搜索按钮&#xff0c;报以下错误。 TypeError: Converting circular structure to J…

全景丨0基础学习VR全景制作,平台篇:如何从素材库发布VR漫游

大家好欢迎观看蛙色平台使用教程 大家可以将创建作品理解成搭建房子&#xff0c;建房子需要基础的砖块、木头、钉子等原材料&#xff0c;房子成品是多种原材料的有机组合&#xff0c;而蛙色VR平台在创建作品前&#xff0c;也需要先准备对应的基础原材料。当前蛙色VR素材上传类型…

C++实现前缀树

文章目录1. 什么是前缀树2. 前缀树的实现2.1 前缀树的基本结构2.2 插入2.3 word出现了几次2.3 word作为前缀出现几次2.4 删除1. 什么是前缀树 假设这里有一个字符串数组&#xff0c;和一个树的根结点&#xff1a; 这个结点的pass意思是&#xff1a;有几个字符通过了这个结点。…

Golang中是否可以无限开辟协程以及如何控制协程的数量?

文章目录1. Golang中是否可以无限开辟协程&#xff1f;2. 不控制goroutine数量引发的问题3. 如何控制goroutine的数量&#xff1f;⭐️3.1 只用有buffer的channel3.2 channel与sync同步组合方式3.3 利用无缓冲channel与任务发送/执行分离方式1. Golang中是否可以无限开辟协程&a…

腾讯轻联中多维表记录id是什么?如何获取记录id?

在腾讯文档智能表、金山轻维表、维格表需要去【更新表格数据】的时候&#xff0c;经常会需要输入记录id&#xff08;英文record id&#xff09;&#xff0c;很多用户也会有疑问&#xff0c;什么是记录id&#xff0c;如何获取记录id等。 金山、维格表、腾讯文档的记录ID是什么&a…

字节跳动CVPR 2023论文精选来啦(内含一批图像生成新研究)

计算机视觉领域三大顶会之一的 CVPR 今年已经开奖啦。 今年的 CVPR 将于六月在加拿大温哥华举办&#xff0c;和往年一样&#xff0c;字节跳动技术团队的同学们收获了不少中选论文&#xff0c;覆盖文本生成图像、语义分割、目标检测、自监督学习等多个领域&#xff0c;其中不少…

[ROC-RK3568-PC] [Firefly-Android] 10min带你了解Camera的使用

&#x1f347; 博主主页&#xff1a; 【Systemcall小酒屋】&#x1f347; 博主追寻&#xff1a;热衷于用简单的案例讲述复杂的技术&#xff0c;“假传万卷书&#xff0c;真传一案例”&#xff0c;这是林群院士说过的一句话&#xff0c;另外“成就是最好的老师”&#xff0c;技术…

SVN利用 AS 进行代码对比的方法

第 1 种&#xff1a;如果我们是从 SVN 检出的项目&#xff0c;并且想比较本地代码与从 SVN 检出时的代码相比都有那些区别&#xff0c;可以按如下步骤操作 如上图所示&#xff0c;在代码编辑区&#xff0c;右键唤出功能菜单&#xff0c;然后选择Subversion&#xff0c;进而会展…

沉浸式翻译 – 支持 PDF、EPUB、网页,可同时显示原文与译文的双语翻译工具

使用的理由 自从谷歌翻译不再对大陆用户提供服务后。内心是一阵酸痛的&#xff0c;毕竟我认识单词单词不认识我啊&#xff0c;这简直是天书一般的存在。 期间网络中的很多大神也是推荐了不少方法让我再次拥抱谷歌翻译&#xff0c;比如教我修改 host 文件什么的&#xff0c;但这…