Spring(三):JavaBean的生命周期

2023-11-19

JavaBean的生命周期

一:基本概念

bean 就是由IOC 容器初始化、装配及管理的对象。
Spring中的bean默认都是单例的,那么单例Bean在多线程程序下如何保证线程安全呢?
Spring的单例是基于BeanFactory也就是Spring容器的,单例Bean在此容器内只有一个,Java的单例是基于 JVM,每个 JVM 内只有一个实例。所以非分布式服务情况下,单例Bean可以保证线程安全。

二:Bean的作用范围

创建一个bean定义,其实质是用该bean定义对应的类来创建真正实例的“配方”。把bean定义看成一个配方很有意义,它与class很类似,只根据一张“处方”就可以创建多个实例。不仅可以控制注入到对象中的各种依赖和配置值,还可以控制该对象的作用域。这样可以灵活选择所建对象的作用域,而不必在Java Class级定义作用域。
Spring Framework支持五种作用域,分别阐述如下表。
我眼中的Bean其实就是一个机器模板,根据一张模板,可以生产出不同的类型机器。
javaBean作用域
五种作用域中,request、session 和 global session 三种作用域仅在基于web的应用中使用(不必关心你所采用的是什么web应用框架),只能用在基于 web 的 Spring ApplicationContext 环境。

详细描述如下:

  1. singleton——唯一 bean 实例

当一个 bean 的作用域为 singleton,那么Spring IoC容器中只会存在一个共享的 bean 实例,并且所有对 bean 的请求,只要 id 与该 bean 定义相匹配,则只会返回bean的同一实例。 singleton 是单例类型(对应于单例模式),就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,但我们可以指定Bean节点的 lazy-init=”true” 来延迟初始化bean,这时候,只有在第一次获取bean时才会初始化bean,即第一次请求该bean时才初始化。 每次获取到的对象都是同一个对象。注意,singleton 作用域是Spring中的缺省作用域。要在XML中将 bean 定义成 singleton ,可以这样配置:

<bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">

也可以通过 @Scope 注解(它可以显示指定bean的作用范围。)的方式

@Service
@Scope("singleton")
public class ServiceImpl{

}
  1. prototype——每次请求都会创建一个新的 bean 实例

当一个bean的作用域为 prototype,表示一个 bean 定义对应多个对象实例。 prototype 作用域的 bean 会导致在每次对该 bean 请求(将其注入到另一个 bean 中,或者以程序的方式调用容器的 getBean() 方法**)时都会创建一个新的 bean 实例。prototype 是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经验,对有状态的 bean 应该使用 prototype 作用域,而对无状态的 bean 则应该使用 singleton 作用域。 在 XML 中将 bean 定义成 prototype ,可以这样配置:

<bean id="account" class="com.foo.DefaultAccount" scope="prototype"/>  
 或者
<bean id="account" class="com.foo.DefaultAccount" singleton="false"/> 

通过 @Scope 注解的方式实现就不做演示了。

注意事项:
作用域为 prototype 的 bean ,其destroy方法并没有被调用。如果 bean 的 scope 设为prototype时,当容器关闭时,destroy 方法不会被调用。对于 prototype 作用域的 bean,有一点非常重要,那就是 Spring不能对一个 prototype bean 的整个生命周期负责:容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。 不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法。但对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责让Spring容器释放被prototype作用域bean占用资源的一种可行方式是,通过使用bean的后置处理器,该处理器持有要被清除的bean的引用)。
谈及prototype作用域的bean时,在某些方面你可以将Spring容器的角色看作是Java new操作的替代者,任何迟于该时间点的生命周期事宜都得交由客户端来处理。
Spring 容器可以管理 singleton 作用域下 bean 的生命周期,在此作用域下,Spring 能够精确地知道bean何时被创建,何时初始化完成,以及何时被销毁。而对于 prototype 作用域的bean,Spring只负责创建,当容器创建了 bean 的实例后,bean 的实例就交给了客户端的代码管理,Spring容器将不再跟踪其生命周期,并且不会管理那些被配置成prototype作用域的bean的生命周期。

  1. request——每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效

request只适用于Web程序,每一次 HTTP 请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,当请求结束后,该对象的生命周期即告结束。 在 XML 中将 bean 定义成 request ,可以这样配置:

<bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>
  1. session——每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效

session只适用于Web程序,session 作用域表示该针对每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前 HTTP session 内有效.与request作用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的 HTTP session 中根据 userPreferences 创建的实例,将不会看到这些特定于某个 HTTP session 的状态变化。当HTTP session最终被废弃的时候,在该HTTP session作用域内的bean也会被废弃掉。

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
  1. globalSession

global session 作用域类似于标准的 HTTP session 作用域,不过仅仅在基于 portlet 的 web 应用中才有意义。Portlet 规范定义了全局 Session 的概念,它被所有构成某个 portlet web 应用的各种不同的 portle t所共享。在global session 作用域中定义的 bean 被限定于全局portlet Session的生命周期范围内。

<bean id="user" class="com.foo.Preferences "scope="globalSession"/>

三:bean的生命周期

在这里插入图片描述
引用:https://zhuanlan.zhihu.com/p/108198655

Bean 的生命周期概括起来就是 4 个阶段

  • 实例化(Instantiation)
  • 属性赋值(Populate)
  • 初始化(Initialization)
  • 销毁(Destruction)

实例化过程:
BeanWrapper调用createBeanInstance方法。

属性赋值:
bean 设置相关属性和依赖

初始化:

(主要了解Bean在实例)

Aware接口:
  • Spring 检测到 bean 实现了 Aware 接口,则会为其注入相应的依赖。
BeanFactory 类型的容器
  • BeanNameAware:注入当前 bean 对应 beanName;
  • BeanClassLoaderAware:注入加载当前 bean 的 ClassLoader(类加载器);
  • BeanFactoryAware:注入 当前BeanFactory容器 的引用。
ApplicationContext 类型的容器
  • EnvironmentAware:注入 Enviroment,一般用于获取配置属性;
  • EmbeddedValueResolverAware:注入 EmbeddedValueResolver(Spring EL解析器),一般用于参数解析;
  • ApplicationContextAware(ResourceLoader、ApplicationEventPublisherAware、MessageSourceAware):注入 ApplicationContext 容器本身。

BeanPostProcessor后置处理器

public interface BeanPostProcessor {
	// 初始化前置处理
	default Object postProcessBeforeInitialization(Object bean,
                  String beanName) throws BeansException {
		return bean;
	}
	// 初始化后置处理
	default Object postProcessAfterInitialization(Object bean,
                  String beanName) throws BeansException {
		return bean;
	}
}

InitializingBean 和 init-method 是 Spring 为 bean 初始化提供的扩展点。(可以扩展初始化逻辑)

DisposableBean 和 destory-method是 Spring 为 bean 销毁提供的扩展点。

bean生命周期详细过程如下:(结合学习)
  1. ResouceLoader加载配置信息
  2. 解析配置信息,生成一个一个的BeanDefintion
  3. BeanDefintion由BeanDefintionRegistry管理起来
  4. BeanFactoryPostProcessor对配置信息进行加工(也就是处理配置的信息,一般通过PropertyPlaceholderConfigurer来实现)
  5. 实例化Bean
  6. 如果该Bean配置/实现了InstantiationAwareBean,则调用对应的方法
  7. 使用BeanWarpper来完成对象之间的属性配置(依赖)
  8. 如果该Bean配置/实现了Aware接口,则调用对应的方法
  9. 如果该Bean配置了BeanPostProcessor的before方法,则调用
  10. 如果该Bean配置了init-method或者实现InstantiationBean,则调用对应的方法
  11. 如果该Bean配置了BeanPostProcessor的after方法,则调用
  12. 将对象放入到HashMap中
  13. 最后如果配置了destroy或者DisposableBean的方法,则执行销毁操作

总结:

首先是实例化、属性赋值、初始化、销毁这 4 个大阶段
再是初始化的具体操作,有 Aware 接口的依赖注入BeanPostProcessor 在初始化前后的处理以及 InitializingBean 和 init-method 的初始化操作;(或**@PostConstruct注解**)
销毁的具体操作,有注册相关销毁回调接口,最后通过DisposableBean 和 destory-method 进行销毁。(@PreDestory注解也可实现)

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring(三):JavaBean的生命周期 的相关文章

  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • 制作一个交互式Windows服务

    我希望我的 Java 应用程序成为交互式 Windows 服务 用户登录时具有 GUI 的 Windows 服务 我搜索了这个 我发现这样做的方法是有两个程序 第一个是服务 第二个是 GUI 程序并使它们进行通信 服务将从 GUI 程序获取
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • 加速代码 - 3D 数组

    我正在尝试提高我编写的一些代码的速度 我想知道从 3d 整数数组访问数据的效率如何 我有一个数组 int cube new int 10 10 10 我用价值观填充其中 然后我访问这些值数千次 我想知道 由于理论上所有 3d 数组都存储在内
  • 磁模拟

    假设我在 n m 像素的 2D 表面上有 p 个节点 我希望这些节点相互吸引 使得它们相距越远吸引力就越强 但是 如果两个节点之间的距离 比如 d A B 小于某个阈值 比如 k 那么它们就会开始排斥 谁能让我开始编写一些关于如何随时间更新
  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity
  • 如何在PreferenceActivity中添加工具栏

    我已经使用首选项创建了应用程序设置 但我注意到 我的 PreferenceActivity 中没有工具栏 如何将工具栏添加到我的 PreferenceActivity 中 My code 我的 pref xml
  • 如何为俚语和表情符号构建正则表达式 (regex)

    我需要构建一个正则表达式来匹配俚语 即 lol lmao imo 等 和表情符号 即 P 等 我按照以下示例进行操作http www coderanch com t 497238 java java Regular Expression D
  • getResourceAsStream() 可以找到 jar 文件之外的文件吗?

    我正在开发一个应用程序 该应用程序使用一个加载配置文件的库 InputStream in getClass getResourceAsStream resource 然后我的应用程序打包在一个 jar文件 如果resource是在里面 ja
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 如何从泛型类调用静态方法?

    我有一个包含静态创建方法的类 public class TestClass public static
  • 静态变量的线程安全

    class ABC implements Runnable private static int a private static int b public void run 我有一个如上所述的 Java 类 我有这个类的多个线程 在里面r
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • 捕获的图像分辨率太大

    我在做什么 我允许用户捕获图像 将其存储到 SD 卡中并上传到服务器 但捕获图像的分辨率为宽度 4608 像素和高度 2592 像素 现在我想要什么 如何在不影响质量的情况下获得小分辨率图像 例如我可以获取或设置捕获的图像分辨率为原始图像分
  • java.lang.IllegalStateException:驱动程序可执行文件的路径必须由 webdriver.chrome.driver 系统属性设置 - Similiar 不回答

    尝试学习 Selenium 我打开了类似的问题 但似乎没有任何帮助 我的代码 package seleniumPractice import org openqa selenium WebDriver import org openqa s
  • 将 List 转换为 JSON

    Hi guys 有人可以帮助我 如何将我的 HQL 查询结果转换为带有对象列表的 JSON 并通过休息服务获取它 这是我的服务方法 它返回查询结果列表 Override public List
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j
  • 使用 xpath 和 vtd-xml 以字符串形式获取元素的子节点和文本

    这是我的 XML 的一部分

随机推荐

  • Android Ble 连接设备失败 onConnectionStateChange status 返回133

    Android Ble 连接设备失败时回调函数 onConnectionStateChange status 返回133 开始找问题 各种mac地址 权限 线程 找了个遍 结果就是返回纹丝不动 又因为 mBluetoothGatt mBlu
  • BUUCTF [极客大挑战 2019]Knife

    打开一看结合题目 就是连接一下菜刀蚁剑 菜刀没用过只有蚁剑 下面用蚁剑实现 设置好URL和链接密码 找到flag文件 打开后找到flag 文件上传漏洞 一句话木马 php Asp Aspx 前端判断文件后缀名可以Burp Suite配置好P
  • pygame小游戏之飞机拼音大作战( 送给娃学拼音的礼物,星际旅行)

    二娃再过一年就该上一年级了 但现阶段的拼音咋都学不进去 买了拼音挂图贴在墙上 拉都拉不到旁边 突发奇想 何不用python的pygame做个小游戏 在玩中也能学习 让学变得有趣 这对搞编程的来说小菜一碟 于是说干就干 两个晚上就成型啦 这里
  • 如何使用条件格式在Excel中突出显示行

    Conditional formatting lets you format cells in an Excel spreadsheet based on the cells content For example you could ha
  • 程序员在囧途之垃圾创业团队

    以前 空虚和寂寞 时写的一篇通过真实案例进行 小说化改编 文 原型中的 我 并不完全代表作者本人 特此拿出和大家分享 也与自己共勉 正文 这年头互联网创业有两个人就算一个团队了 如果是精英组成的团队往往两个人能抵得上十个人 但如果是一帮平庸
  • 接口测试postman和python代码实现

    postman是一个做接口测试的工具 它是谷歌公司的 可谓是根正苗红的大家族 在接口测试领域和它拼的一个手指头也能数得出来 POSTMAN本只是Chrome的一个插件工具 后来谷歌老爹看着小家伙越来越受测试工程师的喜爱 名气越来越大 便做了
  • 【Detectron2】入门03 Faster RCNN + VOC

    在detectron2 data datasets builtin py中可以看到在DatasetCatelog上各个数据集的注册 其中 root即为数据集的基地址 代码指明 root要么是DETECTRON2 DATASETS 要么是da
  • Beyond Compare使用和安装教程

    一 背景 Beyond Compare是一款文件和文件夹比较工具 它能够比较和同步文件夹和文件 并显示它们之间的差异 方便用户决定如何更新和管理它们 Beyond Compare的主要用途包括 文件和文件夹比较 用户可以将两个文件或文件夹进
  • 九种常见排序的比较和实现

    首先排序算法大的可以分为 关键字比较 非关键字比较 关键字比较 关键字比较就是通过关键字之间的比较和移动 从而使整个序列有序 而关键字比较的算法 又可以像下面这样划分 对于排序算法之间的比较 无异于时间复杂度和空间复杂度 看下面这张表格 由
  • OpenCV读取视频并获得相关属性信息

    使用VideoCapture读取视频 video cv2 VideoCapture r prototype mp4 通过下代码确定视频是否读取成功 is open video isOpened 读取成功后 通过VideoCapture ge
  • css实现响应式布局

    一 什么是响应式布局 响应式布局指的是同一页面在不同屏幕尺寸下有不同的布局 传统的开发方式是PC端开发一套 手机端再开发一套 而使用响应式布局只要开发一套就够了 响应式设计与自适应设计的区别 响应式开发一套界面 通过检测视口分辨率 针对不同
  • JQuery使用

    JQuery 框架 注意事项 在导入JQUREY外部文件的时候不可以使用自闭合标签 无效化导入且不报错 不可使用此方式加载 jQuery框架特点 免费开源 轻量级框架 占用资源少 运行速度快 宗旨 write less do more jQ
  • python下载安装教程(Python 3.10版本)

    目录 一 Python下载 二 Python安装 三 检查Python是否安装成功 今天换了新的电脑 需要重新安装python和PyCharm 就简单的写个教程吧 一 Python下载 1 进入Python官网 官网地址 https www
  • 使用http携带token请求第三方接口 并封装参数以post方式请求

    首先准备条件 1 四个jar包 fastjson 1 2 3 jar commons io 2 4 jar commons httpclient 3 1 jar httpcore 4 3 jar slf4j api 1 7 7 jar 这个
  • 范围for语句

    C 新标准提供的范围for语句 这种语句遍历给定序列中个元素并对序列中每一个值执行某种操作 其语法形式是 for declaration expression statement 其中 expression 部分是一个对象 用于表示一个序列
  • tp5 生成随机数

    控制器调用 public function GetRanStr if request gt isPost 生成6位数随机数 return GetRandStr 6 公共方法 生成随机数 param len return string fun
  • 常用与业务密切相关的prompt

    可以在 Bard Bing Claude 2 ChatGPT和 Llama 2 上使用 定义您的业务目的和愿景 提示 我正在 插入行业 创业 我的重点是定义与我的受众产生共鸣的明确目标和愿景 你能指导我制定有意义的愿景声明吗 研究和分析您的
  • android通过JNI用C/C++创建本地文件

    通过jni在本地创建文件 1 在android studio创建基本的jni工程 并且在APP界面成功显示 Hello from C 不会的可以看android studio使用jni 2 在native lib cpp文件中创建文件 为了
  • eclipse导入项目后,项目报红叉的解决方法

    导入项目后 项目报红叉的解决方法 导入别人的项目后 一般都会报错 我之前尝试build path 发现并没有问题 后来发现 点击项目右键 properties 把服务加上Apply and Close就可以了
  • Spring(三):JavaBean的生命周期

    JavaBean的生命周期 一 基本概念 bean 就是由IOC 容器初始化 装配及管理的对象 Spring中的bean默认都是单例的 那么单例Bean在多线程程序下如何保证线程安全呢 Spring的单例是基于BeanFactory也就是S