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

参考:官方文档

1 Bean的作用域

Spring Framework中,总共定义了6种bean 的作用域,其中有4种作用域只有当应用为web应用的时候才有效,并且Spring还支持自定义作用域。

下表描述了这6种作用域:

ScopeDescription
singleton(默认的)在每个Spring IoC容器中,一个bean定义对应只会有唯一的一个bean实例。
prototype一个bean定义可以有多个bean实例。
request一个bean定义对应于单个HTTP 请求的生命周期。也就是说,每个HTTP 请求都有一个bean实例,且该实例仅在这个HTTP 请求的生命周期里有效。该作用域仅适用于WebApplicationContext环境。
session一个bean 定义对应于单个HTTP Session 的生命周期,也就是说,每个HTTP Session 都有一个bean实例,且该实例仅在这个HTTP Session 的生命周期里有效。该作用域仅适用于WebApplicationContext环境。
application一个bean 定义对应于单个ServletContext 的生命周期。该作用域仅适用于WebApplicationContext环境。
websocket一个bean 定义对应于单个websocket 的生命周期。该作用域仅适用于WebApplicationContext环境。

1.1 singleton作用域

singleton作用域表示在整个Spring容器中一个bean定义只生成了唯一的一个bean实例,被Spring容器管理。所有对这个bean的请求和引用都会返回这个bean实例。

下面的图说明了singleton作用域是如何工作的:

在这里插入图片描述

上图中,有3个地方引用了这个bean,这3个引用指向的都是同一个bean实例。

singleton作用域是Spring中默认的作用域,可以在定义bean的时候指定或者不指定都可以,如下:

<!-- 不指定作用域,默认是singleton -->
<bean id="accountService" class="com.something.DefaultAccountService"/>

<!-- 显示指定作用域为singleton -->
<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>

1.2 prototype作用域

prototype作用域表示的是一个bean定义可以创建多个bean实例,有点像一个类可以new多个实例一样。

也就是说,当注入到其他的bean中或者对这个bean定义调用getBean()时,都会生成一个新的bean实例。

作为规则,应该对所有有状态的bean指定prototype作用域,对所有无状态的bean指定singleton作用域。

下图描述了prototype作用域是如何工作的:

在这里插入图片描述

上图中,每个引用对应一个新的bean实例。

请注意,上图中的例子不适用于生产环境。因为DAO通常来说是无状态的bean,应该指定它的作用域为singleton比较合适。

xml中可以这样定义prototype作用域:

<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>

和其他作用域不同的是,Spring并不管理作用域为prototypebean的整个生命周期。Spring容器实例化它、配置它、组装它,然后就将bean交给给使用者了,之后就不会对这个bean进行管理了。因此,Spring不会调用该bean的销毁生命周期回调,使用者必须自己销毁 这个bean并释放资源。如果想让Spring来销毁它并释放资源,请使用自定义的bean post-processor

1.3 当singleton的bean依赖prototype的bean

singletonbean依赖prototypebean时,请注意,这个依赖关系是在实例化时候解析的,并且只解析一次。因此,每个依赖的prototypebean都是一个新的bean实例。

然而,如果一个singletonbean想要在运行时,在每次注入时都能有一个新的prototypebean生成并注入,这是不行的。因为依赖注入在初始化的时候只会注入一次。如果想要在运行时多次注入新的prototypebean,请参考Method Injection

1.4 request、session、application、websocket作用域

requestsessionapplicationwebsocket作用域只有在web环境下才有用。

1.4.1 初始化web配置

为了支持requestsessionapplicationwebsocket作用域,在定义bean之前需要一些初始化配置。

如何完成这个初始化配置取决于你的特定Servlet环境。

如果你在Spring Web MVC中定义这4中作用域,不需要进行初始化配置。因为,Spring使用的DispatcherServlet已经公开了所有相关的状态。

如果你使用的是Servlet 2.5web容器,这些容器不使用SpringDispatcherServlet,你需要注册org.springframework.web.context.request.RequestContextListener。对于Servlet 3.0+的web容器,可以通过编程的方式使用WebApplicationInitializer接口来完成,或者使用xml配置:

<web-app>
    ...
    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
    ...
</web-app>

如果监听器设置遇到问题,可以考虑配置SpringRequestContextFilter

<web-app>
    ...
    <filter>
        <filter-name>requestContextFilter</filter-name>
        <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>requestContextFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    ...
</web-app>

DispatcherServletRequestContextListenerRequestContextFilter 共同做了相同的事,即将HTTP请求对象绑定到服务该请求的线程。这使得请求作用域和会话作用域的bean在调用链的更下游可用。

1.4.2 request作用域

下面的xml配置指定了bean的作用域为request

<bean id="loginAction" class="com.something.LoginAction" scope="request"/>

Spring为每一个HTTP请求创建一个新的LoginActionbean。每个bean之间不可见,当请求结束,对应的bean将被丢弃。

当使用注解定义bean的时候,可以通过使用@RequestScope注解设定request作用域:

@RequestScope
@Component
public class LoginAction {
    // ...
}

1.4.3 session作用域

xml中可以这样定义bean的作用域为session作用域:

<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>

Spring为每个HTTP Session创建一个新的UserPreferencesbean。每个bean之间是不可见的,只属于对应的Session,当Session销毁的时候,对应的bean也会被销毁。

当使用注解定义bean的时候,可以通过@SessionScope注解设定session作用域:

@SessionScope
@Component
public class UserPreferences {
    // ...
}

1.4.4 application作用域

xml中可以这样定义bean的作用域为application作用域:

<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>

Spring为整个web上下文创建一个AppPreferencesbean。也就是说,这个bean作用域是在ServletContext级别,它是作为ServletContext的一个属性存在的。

这和singleton作用域很像,但是有两点不同:

  • application作用域的bean是每个ServletContext只有一个;而singleton作用域是每个SpringApplicationContext只有一个。两者的范围不同。
  • application作用域的bean是属于ServletContext的,作为ServletContext的属性,是可见的。

当使用注解定义bean的时候,可以通过@ApplicationScope注解设定application作用域:

@ApplicationScope
@Component
public class AppPreferences {
    // ...
}

1.4.5 被设定了作用域的bean作为依赖项注入

没太看懂,详见官方文档

  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Framework,共定义了6bean的作用域,其有4作用域只有当应用为web应用的时候才有效,并且Spring还支持自定义作用域。 与此类似,在Spring Boot,可以使用这些作用域来管理bean的生命周期。 Spring Boot支持的作用域包括: 1. 单例(Singleton)作用域:在整个应用程序的生命周期只创建一个实例。所有的请求都共享同一个实例。 2. 原型(Prototype)作用域:每次请求都会创建一个新的实例。 3. 会话(Session)作用域:在同一个会话,共享同一个实例。 4. 请求(Request)作用域:在同一个请求,共享同一个实例。 5. application作用域:在Spring,application作用域类似于singleton作用域,但是在web应用有不同的使用方式。application作用域bean是每个ServletContext只有一个,属于ServletContext的属性,是可见的。 6. WebSocket作用域:这是一特殊的作用域,用于在WebSocket连接的生命周期内共享bean实例。 在Spring Boot,可以使用注解来指定bean的作用域,例如@Scope("singleton")指定为单例作用域,@Scope("prototype")指定为原型作用域。对于application作用域bean,可以使用@Scope("application")来指定。 总之,Spring Boot提供了多作用域来管理bean的生命周期,开发人员可以根据应用的需求选择适合的作用域来管理bean的创建和销毁。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【SpringBoot笔记10SpringBean的6作用域](https://blog.csdn.net/u011441473/article/details/122692192)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值