Spring之Bean详解

Spring之Bean详解

什么是Bean?

在Spring中,Bean是指由Spring容器管理的对象,这些对象是由Spring IoC容器负责创建、组装和管理的。Bean可以是Java类的实例,也可以是其他Spring管理的组件,例如数据源、事务管理器等。

怎么声明一个Bean?

Bean的声明可以通过注解或者XML文件进行配置,这里主要使用现在流行的注解模式进行讲解

通过类声明Bean

在Bean对象对应的类上添加@Component 、@Repository 、@Service、@Controller中的任意一个注解,但是要注意这几个注解一般是为了让开发人员识别Bean对象的作用,比如@Repository : 对应持久层即 Dao 层,主要用于数据库相关操作。

通过@Bean声明Bean
@Configuration
public class RedisTemplateConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        redisTemplate.setKeySerializer(RedisSerializer.string());
        return redisTemplate;
    }
}
怎么样注入Bean对象?

常见的注入方式有@AutoWired和@Resource这两个注解

@Component
public class AnalysisController {

    @Resource
    private Service service1;
  
  	@Autowired
    private Service service2;
  
}
@AutoWired和@Resource区别

Autowired 属于 Spring 内置的注解,默认的注入方式为byType(根据类型进行匹配),也就是说会优先根据接口类型去匹配并注入 Bean (接口的实现类)。

这会有什么问题呢? 当一个接口存在多个实现类的话,byType这种方式就无法正确注入对象了,因为这个时候 Spring 会同时找到多个满足条件的选择,默认情况下它自己不知道选择哪一个。

例如:现在容器中有两个Bean [<serviceImpl1, Service>, <serviceImpl2, Service>], @Autowired会先根据Service类型找对应的Bean,找到了名为serviceImpl1、serviceImpl2这两个Bean,然后byName,看是否有对应的名为service1的Bean,发现都没有,报错

区别

ResourceAutowired相反,它是先byName找,如果没找到,再byType

Bean的作用域
  1. 单例(Singleton):最常用的作用域,也是Spring默认的作用域
    • 说明: 默认作用域,一个容器中只存在一个Bean实例。
    • 生命周期: 在容器启动时创建,直到容器关闭时销毁。
    • 应用场景: 适用于无状态的、共享的Bean,例如服务层组件。
@Scope("singleton")
public class MySingletonBean {
    // ...
}
  1. 原型(Prototype):
  • 说明: 每次请求都会创建一个新的Bean实例。
  • 生命周期: 在每次请求时创建,使用后不受容器管理,由Java垃圾回收机制负责销毁。
  • 应用场景: 适用于有状态的、独立的Bean,例如控制器、工具类等。
@Scope("prototype")
public class MyPrototypeBean {
    // ...
}
  1. 会话(Session):
  • 说明: 在Web应用中,每个会话都会创建一个Bean实例。
  • 生命周期: 在会话创建时创建,会话销毁时销毁。
  • 应用场景: 主要用于Web应用中的会话管理,例如保存用户的登录状态。
@Scope("session")
public class MySessionBean {
    // ...
}
  1. 请求(Request):
  • 说明: 在Web应用中,每个请求都会创建一个Bean实例。
  • 生命周期: 在每次HTTP请求时创建,请求结束时销毁。
  • 应用场景: 主要用于Web应用中的请求处理,例如保存用户请求的临时数据。
@Scope("request")
public class MyRequestBean {
    // ...
}
  1. 全局会话(Global Session):
  • 说明: 仅在Web应用中有效,全局会话是一组会话的抽象,由Servlet容器管理。
  • 生命周期: 在全局会话创建时创建,全局会话销毁时销毁。
  • 应用场景: 主要用于Portlet应用中,用于跨多个会话的共享Bean。
@Scope("globalSession")
public class MyGlobalSessionBean {
    // ...
}

选择适当的作用域取决于应用的需求,通过合理配置作用域可以提高应用性能、降低资源消耗,并更好地管理Bean的生命周期。

Bean的线程安全问题

在Spring中,Bean的线程安全问题主要涉及到在多线程环境下共享的Bean实例。Spring默认情况下,Bean是单例的,即在整个应用中只有一个实例。在多线程环境下,如果多个线程同时访问和修改这个单例Bean,就可能引发线程安全问题。

我们这里以最常用的两种作用域 prototype 和 singleton 为例介绍。几乎所有场景的 Bean 作用域都是使用默认的 singleton ,重点关注 singleton 作用域即可。

prototype 作用域下,每次获取都会创建一个新的 bean 实例,不存在资源竞争问题,所以不存在线程安全问题。singleton 作用域下,IoC 容器中只有唯一的 bean 实例,可能会存在资源竞争问题(取决于 Bean 是否有状态)。如果这个 bean 是有状态的话,那就存在线程安全问题(有状态 Bean 是指包含可变的成员变量的对象)。

不过,大部分 Bean 实际都是无状态(没有定义可变的成员变量)的(比如 Dao、Service),这种情况下, Bean 是线程安全的。

对于有状态单例 Bean 的线程安全问题,常见的有两种解决办法:

  1. 在 Bean 中尽量避免定义可变的成员变量。
  2. 在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。

Bean的生命周期

在Spring框架中,Bean的生命周期是管理和控制对象创建、初始化、使用和销毁的全过程。理解和掌握Bean的生命周期对于使用Spring框架开发应用程序是非常重要的一部分。

Bean的生命周期管理是为了确保在对象创建、初始化、使用和销毁的过程中,Spring容器能够正确地执行各种任务,如依赖注入、初始化方法、销毁方法等。通过Bean的生命周期管理,Spring可以更好地控制对象的行为,提高系统的可维护性和灵活性。

Bean的生命周期包括以下阶段:

Spring Bean 生命周期

  1. 实例化(Instantiation): Spring容器根据配置文件或注解等信息,实例化Bean对象。这一阶段涉及到类的加载和实例化过程。
  2. 属性赋值(Populate Properties): Spring容器为Bean注入属性值,包括基本数据类型、引用类型等。这一阶段涉及到依赖注入。
  3. 初始化前(Initialization): 在调用Bean的初始化方法之前,Spring容器可以允许用户自定义一些初始化操作。这一阶段涉及到InitializingBean接口、@PostConstruct注解等。
  4. 初始化(Initialization): 调用Bean的初始化方法,完成Bean的初始化。这一阶段涉及到init-method配置、@PostConstruct注解等。
  5. 初始化后(Initialization): 在调用Bean的初始化方法之后,Spring容器可以允许用户自定义一些初始化操作。这一阶段涉及到InitializingBean接口、@PostConstruct注解等。
  6. 使用中(In Use): Bean对象被正常使用,处于活动状态。
  7. 销毁前(Destruction): 在调用Bean的销毁方法之前,Spring容器可以允许用户自定义一些销毁操作。这一阶段涉及到DisposableBean接口、@PreDestroy注解等。
  8. 销毁(Destruction): 调用Bean的销毁方法,完成Bean的销毁。这一阶段涉及到destroy-method配置、@PreDestroy注解等。

总结

Bean的生命周期是Spring框架的一个重要概念,通过生命周期管理,Spring容器能够更好地控制对象的创建、初始化、使用和销毁过程。理解Bean的生命周期有助于开发者更好地利用Spring框架的特性,编写出高质量、易维护的应用程序。在实际应用中,可以通过实现特定接口、配置初始化和销毁方法、使用注解等方式来定制Bean的生命周期。

如果觉得本篇文章对于你理解Spring的Bean有帮助,可否点个小赞😺;篇幅较长建议收藏🫠;关注一手等待后续更新更多干货🚀

参考链接:https://javaguide.cn/system-design/framework/spring/spring-knowledge-and-questions-summary.html

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

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

相关文章

【树上倍增】【割点】 【换根法】3067. 在带权树网络中统计可连接服务器对数目

作者推荐 视频算法专题 本文涉及知识点 树上倍增 树 图论 并集查找 换根法 深度优先 割点 LeetCode3067. 在带权树网络中统计可连接服务器对数目 给你一棵无根带权树&#xff0c;树中总共有 n 个节点&#xff0c;分别表示 n 个服务器&#xff0c;服务器从 0 到 n - 1 编号…

Wireshark_labs TCP

在本实验中&#xff0c;我们将详细研究著名的TCP协议的行为。我们将通过从您的电脑向远程服务器传输一份150KB 的文件(一份Lewis Carrol 的“爱丽丝梦游仙境”文本)&#xff0c; 并分析TCP传输内容的发送和接收过程来实现。我们将研究TCP对序列和确认号的使用&#xff0c;以提供…

Proxmox VE安装CentOS

1、下载CentOS镜像文件 阿里巴巴开源镜像站&#xff1a; https://developer.aliyun.com/mirror/ CentOS 镜像文件 https://mirrors.aliyun.com/centos/8.5.2111/isos/x86_64/CentOS-8.5.2111-x86_64-dvd1.iso 2、上传ISO镜像 选择ISO镜像上传 3、创建虚拟机 1、点击【创…

python转换json

import json import os from enum import Enumclass LaneDirectionType(int, Enum):LaneDirectionType_Unknown -1 # 类型未知OneWay 1 # 单向TwoWay 2 # 双向# 颜色类型 class ColorCombo(int, Enum):NOUSE 0 # 默认值UNKNOWN 1000 # 未定义WHITE 1 # 白色(默认值…

俄罗斯套娃 (Matryoshka) 嵌入模型概述

在这篇博客中&#xff0c;我们将向你介绍俄罗斯套娃嵌入的概念&#xff0c;并解释为什么它们很有用。我们将讨论这些模型在理论上是如何训练的&#xff0c;以及你如何使用 Sentence Transformers 来训练它们。 除此之外&#xff0c;我们还会告诉你怎么用这种像套娃一样的俄罗斯…

【Vue】vue3 在图片上渲染 OCR 识别后的文本框、可复制文本组件

需求 后面返回解析后的文本和四角坐标&#xff0c;在图片上渲染成框&#xff0c;并且可复制。图片还可以缩放、拖拽 实现 这里要重点讲下关于OCR文本框的处理&#xff1a; 因为一些文字可能是斜着放的&#xff0c;所有我们要特殊处理&#xff0c;根据三角函数来计算出它的偏…

分布式ID生成策略-雪花算法Snowflake

分布式ID生成策略-雪花算法Snowflake 一、其他分布式ID策略1.UUID2.数据库自增与优化2.1 优化1 - 共用id自增表2.2 优化2 - 分段获取id 3.Reids的incr和incrby 二、雪花算法Snowflake1.雪花算法的定义2.基础雪花算法源码解读3.并发1000测试4.如何设置机房和机器id4.雪花算法时钟…

短剧系统开发:一种新型的娱乐方式

一、引言 随着科技的快速发展&#xff0c;人们的生活方式也在逐渐改变。在娱乐领域&#xff0c;短剧作为一种新型的娱乐方式&#xff0c;正在受到越来越多人的喜爱。短剧以其短小精悍、情节紧凑、易于观看等特点&#xff0c;迅速占领了市场。因此&#xff0c;开发一款短剧系统…

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的数码管显示应用

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的数码管显示应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍TM1638键盘数码管模块概述TM1638键盘数码管…

pytorch什么是梯度

目录 1.导数、偏微分、梯度1.1 导数1.2 偏微分1.3 梯度 2. 通过梯度求极小值3. learning rate3. 局部最小值4. Saddle point鞍点 1.导数、偏微分、梯度 1.1 导数 对于yx 2 2 2 的导数&#xff0c;描述了y随x值变化的一个变化趋势&#xff0c;导数是个标量反应的是变化的程度&…

NoSQL--3.MongoDB配置(Linux版)

目录 2.2 Linux环境下操作 2.2.1 传输MongoDB压缩包到虚拟机&#xff1a; 2.2.2 启动MongoDB服务&#xff1a; 2.2 Linux环境下操作 2.2.1 传输MongoDB压缩包到虚拟机&#xff1a; &#xff08;笔者使用XShell传输&#xff09; 如果不想放在如图的路径&#xff0c;删除操作…

基于springboot+vue实现学校田径运动会系统项目【项目源码+论文说明】计算机毕业设计

基于springbootvue实现学校田径运动会系统演示 摘要 随着互联网普及率的提高&#xff0c;互联网与人们日常生活的关系越来越密切&#xff0c;越来越多学校也正在着力建设自己的信息化管理系统&#xff0c;学校根据自身的发展及社会发展的需要&#xff0c;开始将传统的运动会成…

Golang模糊测试实践

模糊测试可以简单快速的自动化构建测试用例&#xff0c;尽量遍历各种可能的输入场景&#xff0c;从而保证函数代码覆盖尽可能多的边缘场景。Go原生内置了模糊测试的支持&#xff0c;如果善加利用&#xff0c;可以有效提升Go代码的质量。原文: Fuzz Testing in Golang 题图由Lex…

Hadoop配置日志的聚集——jobhistory不显示任务问题

问题&#xff1a; 一开始job history是正常的&#xff0c;配置了日志的聚集以后不管做什么任务都不显示任务&#xff0c;hdfs是正常运行&#xff0c;而且根据配置步骤都重启过了。 下面先po出日志聚集的操作步骤&#xff0c;再讲问题 1.配置yarn-site.xml cd $HADOOP_HOME/e…

0基础跨考408|一战上岸复盘及经验分享

基础阶段‼️ 王道的四本书的选择题部分要都做完、订正完。 王道的四门视频课要一轮刷完&#xff08;或者题主在B站看了其他的老师&#xff0c;这其实也是算一轮的&#xff0c;只要题主是认真学习了的&#xff0c;题主说自己不知道看什么课&#xff0c;王道就好了&#xff09;…

kibana配置 dashbord,做可视化展示

一、环境介绍 这里我使用的kibana版本为7.17版本。 语言选择为中文。 需要已经有es&#xff0c;已经有kibana&#xff0c;并且都能正常访问。 二、背景介绍 kibana的可视化界面&#xff0c;可以配置很多监控统计界面。非常方便&#xff0c;做数据的可视化展示。 这篇文章&…

【四】【SQL Server】如何运用SQL Server中查询设计器通关数据库期末查询大题

数据库学生选择1122 数据库展示 course表展示 SC表展示 student表展示 数据库学生选课1122_3 第十一题 第十二题 第十三题 第十四题 第十五题 数据库学生选课1122_4 第十六题 第十七题 第十八题 第十九题 第二十题 数据库学生选课1122_5 第二十一题 第二十二题 结尾 最后&…

恒驰上云规划实施解决方案上线华为云官网

华为云与伙伴共同打造联合解决方案 已成为更多企业的数字化转型利器 1月恒驰上云规划实施解决方案 完成上市宣讲并正式上架华为云官网 恒驰上云规划实施解决方案能力全景图&#xff1a;融合厂商云服务能力&#xff0c;一站式高效云迁移 从深入了解企业的本地IT环境、业务特点…

查看kafka消息消费堆积情况

查看主题命令 展示topic列表 ./kafka-topics.sh --list --zookeeper zookeeper_ip:2181描述topic ./kafka-topics.sh --describe --zookeeper zookeeper_ip:2181 --topic topic_name查看topic某分区偏移量最大&#xff08;小&#xff09;值 ./kafka-run-class.sh kafka.too…

Git——Upload your open store

0.default config ssh-keygen -t rsa #之后一路回车,当前目录.ssh/下产生公私钥 cat ~/.ssh/id_rsa.pub #复制公钥到账号 git config --global user.email account_email git config --global user.name account_name1. 上传一个公开仓库 查看当前分支&#xff1a; git branc…