Spring(十):Bean Scopes(作用范围)

  使用 Spring 框架,在定义 Bean 时,通常不指定其作用范围而使用默认的配置,可能会对 Spring Bean 的作用范围不甚了解。Spring 给 Bean 定义的作用范围提供了灵活的配置,开箱即用,Spring Framework 支持 六个作用范围,其中四个范围只有在使用支持 Web 的 ApplicationContext时才能使用,还提供了自定义作用范围。

  查看了下 Spring 5.0.9 Release 版本关于 Spring Bean scopes章节内容,在此做个记录,至于是否和其它版本有区别暂未对比。  

Bean scopes

Scope Description
singleton (Default) Scopes a single bean definition to a single object instance per Spring IoC container.
prototype Scopes a single bean definition to any number of object instances.
request Scopes a single bean definition to the lifecycle of a single HTTP request; that is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
session Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
application Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
websocket Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.

作用范围

Bean 的作用范围设置主要有两种:一种是XML配置中添加 scope 属性,第二种是在JavaConfig配置中定义 Bean 时添加声明作用域的注解。

1
<bean id="accountService" class="com.foo.DefaultAccountService" scope="prototype"/>
1
2
3
4
5
@Bean
@Scope(value = "prototype")
public User user(){
return new User();
}

获取 Bean 主要有两种方式:注入和通过 getBean()方法根据 Bean Id 查找。

Singleton scope

六大作用域,其中 request, session, application, websocket 四大作用域只有在使用支持 Web 的 ApplicationContext 时才可用(可以创建WebApplicationContext),若是用在常规的 Spring IoC容器(如 ClassPathXmlApplicationContext)一起使用,则会抛出 IllegalStateException 异常,表示未知的 Bean 作用域。

单例范围,Spring 默认的作用范围(没有显式配置 Bean 的作用范围),当定义一个 Bean 的作用范围是单例时,Spring IoC容器只创建该 Bean 的一个实例,并存储在缓存中,对该命名 Bean 的所有请求和引用都返回缓存中的此对象。

Spring 的单例 Bean 不同于 Gang of Four(GoF)模式中定义的 Singleton 模式。GoF Singleton 模式是对对象的范围进行硬编码,使得每个 ClassLoader 创建一个且只有一个类对象的实例。

Spring 单例的范围的最好结合容器和每个 Bean 来描述,如果在单个 Spring 容器中给类定义一个 Bean,则 Spring 容器将根据 Bean 的定义创建该类的唯一实例

Prototype scope

原型范围,Bean 的非单例原型作用范围导致每次发出对该 Bean 的请求时都会创建一个新的实例。通常,对所有 有状态 Bean 使用原型范围,对无状态 Bean 使用单例范围

与其它作用域相比,Spring 不管理原型 Bean 的完整生命周期,不记录该原型实例,不会调用已配置的销毁生命周期的回调。如果要让 Spring 容器释放原型范围内的 Bean 所持有的资源,可以自定义 Bean 后处理器,它包含对需要清理的 Bean 的引用。Spring 容器关于原型范围 Bean 的操作相当于 Java new 运算符。

Request scope

Spring 容器会给每个 HTTP 请求创建一个新的实例,Request scope 是 HTTP 请求级别。使用注解驱动或 JavaConfig 时,可使用@RequestScope来声明该 Bean 的作用范围。

1
<bean id="loginAction" class="com.foo.LoginAction" scope="request"/>
1
2
3
4
5
@RequestScope
@Component
public class LoginAction {
// ...
}

Session scope

Spring 容器会给每个生存期内的 Session 创建一个 Bean 的新实例,Session scope 是 Session 级别。使用注解驱动或 JavaConfig 时,可使用@SessionScope 来声明该 Bean 的作用范围。

1
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
1
2
3
4
5
@SessionScope
@Component
public class UserPreferences {
// ...
}

Application scope

Spring 容器通过对整个 Web应用程序创建一个新的实例,作为常规的 ServletContext 属性存储,作用域是 ServletContext 级别。注意是不同于 Spring 的 ApplicationContext。使用注解驱动或 JavaConfig 时,可使用@ApplicationScope来声明该 Bean 的作用范围。

1
<bean id="appPreferences" class="com.foo.AppPreferences" scope="application"/>
1
2
3
4
5
@ApplicationScope
@Component
public class AppPreferences {
// ...
}

Spring(十):Bean Scopes(作用范围)

http://blog.gxitsky.com/2018/03/28/Spring-10-bean-scope/

作者

光星

发布于

2018-03-28

更新于

2022-06-17

许可协议

评论