【SpringBoot笔记10】Spring中Bean的6种作用域

参考:官方文档
1 Bean的作用域
在 中,总共定义了6种bean 的作用域,其中有4种作用域只有当应用为web应用的时候才有效 , 并且还支持自定义作用域 。
下表描述了这6种作用域:
(默认的)在每个 IoC容器中,一个bean定义对应只会有唯一的一个bean实例 。
一个bean定义可以有多个bean实例 。
一个bean定义对应于单个HTTP 请求的生命周期 。也就是说,每个HTTP 请求都有一个bean实例,且该实例仅在这个HTTP 请求的生命周期里有效 。该作用域仅适用于t环境 。
一个bean 定义对应于单个HTTP的生命周期,也就是说,每个HTTP都有一个bean实例,且该实例仅在这个HTTP的生命周期里有效 。该作用域仅适用于t环境 。
一个bean 定义对应于单个 的生命周期 。该作用域仅适用于t环境 。
一个bean 定义对应于单个 的生命周期 。该作用域仅适用于t环境 。

【SpringBoot笔记10】Spring中Bean的6种作用域

文章插图
1.1 作用域
作用域表示在整个容器中一个bean定义只生成了唯一的一个bean实例,被容器管理 。所有对这个bean的请求和引用都会返回这个bean实例 。
下面的图说明了作用域是如何工作的:
上图中,有3个地方引用了这个bean,这3个引用指向的都是同一个bean实例 。
作用域是中默认的作用域,可以在定义bean的时候指定或者不指定都可以,如下:

1.2 作用域
作用域表示的是一个bean定义可以创建多个bean实例 , 有点像一个类可以new多个实例一样 。
也就是说,当注入到其他的bean中或者对这个bean定义调用()时,都会生成一个新的bean实例 。
作为规则,应该对所有有状态的bean指定作用域,对所有无状态的bean指定作用域 。
下图描述了作用域是如何工作的:
上图中 , 每个引用对应一个新的bean实例 。
请注意,上图中的例子不适用于生产环境 。因为DAO通常来说是无状态的bean,应该指定它的作用域为比较合适 。
在xml中可以这样定义作用域:

【SpringBoot笔记10】Spring中Bean的6种作用域

文章插图
和其他作用域不同的是,并不管理作用域为的bean的整个生命周期 。容器实例化它、配置它、组装它 , 然后就将bean交给给使用者了,之后就不会对这个bean进行管理了 。因此 , 不会调用该bean的销毁生命周期回调,使用者必须自己销毁 这个bean并释放资源 。如果想让来销毁它并释放资源,请使用自定义的bean post- 。
1.3 当的bean依赖的bean
当的bean依赖的bean时,请注意,这个依赖关系是在实例化时候解析的,并且只解析一次 。因此,每个依赖的的bean都是一个新的bean实例 。
然而,如果一个的bean想要在运行时 , 在每次注入时都能有一个新的的bean生成并注入 , 这是不行的 。因为依赖注入在初始化的时候只会注入一次 。如果想要在运行时多次注入新的的bean,请参考。
1.4 、、、作用域
、、、作用域只有在web环境下才有用 。
1.4.1 初始化web配置
为了支持、、、作用域,在定义bean之前需要一些初始化配置 。
如何完成这个初始化配置取决于你的特定环境 。
如果你在 Web MVC中定义这4中作用域,不需要进行初始化配置 。因为 , 使用的已经公开了所有相关的状态 。
如果你使用的是 2.5web容器,这些容器不使用的 , 你需要注册org..web...er 。对于 3.0+的web容器,可以通过编程的方式使用lizer接口来完成,或者使用xml配置:
...org.springframework.web.context.request.RequestContextListener...
如果监听器设置遇到问题 , 可以考虑配置的:
...requestContextFilterorg.springframework.web.filter.RequestContextFilterrequestContextFilter/*...
、er和 共同做了相同的事,即将HTTP请求对象绑定到服务该请求的线程 。这使得请求作用域和会话作用域的bean在调用链的更下游可用 。
1.4.2 作用域
下面的xml配置指定了bean的作用域为:
【【SpringBoot笔记10】Spring中Bean的6种作用域】