博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Bean 作用域详解
阅读量:3738 次
发布时间:2019-05-22

本文共 2373 字,大约阅读时间需要 7 分钟。

在 Spring 中,那些组成应用程序的主体,以及由 Spring IOC 容器所管理的对象,被称之为 bean。简单地讲,bean 就是由 IOC 容器初始化、装配及管理的对象,除此之外,bean 就与应用程序中的其他对象没有什么区别了,而 bean 的定义以及 bean 相互间的依赖关系,将通过配置元数据来描述。

Spring 中的 bean 默认都是单例的,在多线程程序下,这些单例 Bean 是如何保证线程安全的呢?

例如对于 Web 应用来说,Web 容器对于每个用户的请求,都会创建一个单独的 Sevlet 线程来处理请求,引入 Spring 框架后,每个 Action 都是单例的,那么对于 Spring 托管的单例 Service Bean,如何保证其安全呢?

答案是:Spring 的单例是基于 BeanFactory,也就是 Spring 容器的,单例 Bean 在此容器内只有一个,Java 的单例是基于 JVM,每个 JVM 内只有一个实例。

在大多数情况下。单例 bean 是很理想的方案。不过,有时候系统所使用的类是易变的,它们会保持一些状态,因此重用是不安全的。在这种情况下,将 class 声明为单例就显得不是那么明智了。因为对象会被污染,重用的时候可能会出现意想不到的问题,所以 Spring 定义了支持多种作用域的 bean。

bean 的作用域

创建一个 bean 定义,其实质是用该 bean 定义对应的类来创建真正实例的 “配方”。把 bean 定义看成是配方很有意义,它与 class 很类似,只根据一张 “处方” 就可以创建多个实例,不仅可以控制注入到对象中的各种依赖和配置值,还可以控制该对象的作用域。这样可以灵活选择所建对象的作用域,而不必在 Java Class 级定义作用域。如下表所示,Spring Framework 支持五种作用域。

9709135-4ee1f78820805da2.jpg
Spring 五种作用域

以上五种作用域中,request、sessionglobal session 三种作用域,仅能用在基于 web 的 Spring ApplicationContext 环境。

singleton:唯一 bean 实例

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

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

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

prototype:每次请求都会创建一个新的 bean 实例

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

总之,对有状态的 bean 应该使用 prototype 作用域,而对无状态的 bean 则应该使用 singleton 作用域。在 XML 中将 bean 定义成 prototype ,可以这样配置:

# 或者

request:每次 HTTP 请求都会产生新的 bean,该 bean 仅在当前 HTTP request 内有效

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

session:每次 HTTP 请求都会产生新的 bean,该 bean 仅在当前 HTTP session 内有效

session 只适用于 Web 程序,session 作用域表示该针对每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前 HTTP session 内有效。当HTTP session 最终被废弃的时候,在该 HTTP session 作用域内的 bean 也会被销毁掉。

globalSession:伴随应用本身的全局作用域

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

转载地址:http://hnsin.baihongyu.com/

你可能感兴趣的文章
2020年高教社杯全国大学生数学建模竞赛赛题 B题分析与思路!(持续更新)
查看>>
蓝桥杯真题 18省4-测试次数 x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。 各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐
查看>>
蓝桥杯真题 19省3-数列求值 给定数列 1, 1, 1, 3, 5, 9, 17, …,从第 4 项开始,每项都是前 3 项的和。求第 20190324 项的最后 4 位数字。
查看>>
蓝桥杯真题 19省4-数的分解 把 2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法? 注意交换 3 个整数的顺
查看>>
大小写字母转换函数tolower();的用法
查看>>
蓝桥杯 15校4-7对数字 今有7对数字:两个1,两个2,两个3,...两个7,把它们排成一行。 要求,两个1间有1个其它数字,两个2间有2个其它数字,以此类推,两个7之间有7个其它数字。如下就是
查看>>
蓝桥杯 算法训练 - 寂寞的数 道德经曰:一生二,二生三,三生万物。   对于任意正整数n,我们定义d(n)的值为为n加上组成n的各个数字的和。例如,d(23)=23+2+3=28, d(1481
查看>>
蓝桥杯真题 17省10-k倍区间 给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i
查看>>
TCP协议的流量控制
查看>>
TCP连接的三次握手过程,为什么不是两次或四次?
查看>>
小白都能看懂的DNS解析过程
查看>>
HTTP和HTTPS的区别?描述HTTPS的工作过程
查看>>
简述一下HTTP的状态码
查看>>
20210227vulhub靶场之环境配置---无法获得靶机IP的疑难解决方式(可以解决VBox和VMware不兼容问题)
查看>>
20210226web渗透学习之SSRF总结
查看>>
2021-06-01web渗透学习之sqlserver提权(转)
查看>>
2021-06-04msf结合漏扫模块suggester提权
查看>>
hdfs的api操作
查看>>
mapreduce的组成及原理
查看>>
大数据之Flume
查看>>