bean范围
当您创建一个 bean 定义时,您创建了一个用于创建由该 bean 定义的类的实际实例的方法。您可以从这个模板创建许多对象实例。
Spring 框架支持六个范围,其中四个仅在您使用 web应用时可用
范围 | 描述 |
---|---|
singleton | (默认)将单个 bean 定义限定为每个 Spring IoC 容器的单个对象实例。 |
prototype | 将单个 bean 定义限定为任意数量的对象实例。 |
request | 将单个 bean 定义限定为单个 HTTP 请求的生命周期。也就是说,每个 HTTP 请求都有自己的 bean 实例,该实例是在单个 bean 定义的后面创建的。仅在 Web 感知 Spring 的上下文中有效ApplicationContext 。 |
session | 将单个 bean 定义限定为 HTTP 的生命周期Session 。仅在 Web 感知 Spring 的上下文中有效ApplicationContext 。 |
application | 将单个 bean 定义限定为ServletContext . 仅在 Web 感知 Spring 的上下文中有效ApplicationContext 。 |
WebSocket | 将单个 bean 定义限定为WebSocket . 仅在 Web 感知 Spring 的上下文中有效ApplicationContext 。 |
单例范围
只有一个单例 bean 的共享实例被管理
原型范围
导致每次对特定 bean 发出请求时都会创建一个新的 bean 实例。
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
请求、会话、应用程序和 WebSocket 范围
在request
,session
,application
,和websocket
范围只有当你使用一个基于web的Spring可ApplicationContext
实现
初始 Web 配置
为了支持豆的范围界定在request
,session
,application
,和 websocket
(即具有web作用域bean),需要做少量的初始配置定义你的豆之前。
如何完成此初始设置取决于您的特定 Servlet 环境。
对于 Servlet 3.0+,这可以通过使用WebApplicationInitializer
接口以编程方式完成。或者,或者对于较旧的容器,将以下声明添加到您的 Web 应用程序的web.xml
文件中:
<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>
或者,如果您的侦听器设置存在问题,请考虑使用 Spring 的 RequestContextFilte
r
<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>
请求范围
考虑以下 bean 定义的 XML 配置:
<bean id="loginAction" class="com.something.LoginAction" scope="request"/>
Spring 容器通过为每个 HTTP 请求LoginAction
使用 bean 定义来创建 bean 的新实例。loginAction
也就是说, loginAction
bean 的作用域是 HTTP 请求级别。
当使用注解驱动的组件或 Java 配置时,@RequestScope
注解可用于将组件分配给request
范围。以下示例显示了如何执行此操作:
@RequestScope
@Component
public class LoginAction {
// ...
}
会话范围
考虑以下 bean 定义的 XML 配置:
<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>
Spring 容器通过在单个 HTTP 的生命周期中会话
使用 bean 定义来创建 bean 的新实例。
在使用注解驱动的组件或 Java 配置时,您可以使用 @SessionScope
注解将组件分配给session
范围。
@SessionScope
@Component
public class UserPreferences {
// ...
}
应用范围
考虑以下 bean 定义的 XML 配置:
<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>
Spring 容器通过为整个 Web 应用程序应用
使用一次 bean 定义来创建 bean 的新实例。
在使用注解驱动的组件或 Java 配置时,您可以使用 @ApplicationScope
注解将组件分配给application
范围。以下示例显示了如何执行此操作:
@ApplicationScope
@Component
public class AppPreferences {
// ...
}
WebSocket 范围
WebSocket 范围与 WebSocket 会话的生命周期相关联,适用于 STOMP over WebSocket 应用程序
自定义范围
bean 作用域机制是可扩展的。您可以定义自己的范围,甚至重新定义现有范围,尽管后者被认为是不好的做法,并且您不能覆盖内置singleton
和prototype
范围。