The scopes request
, session
, application
and websocket
are only
available if you use the implementation ApplicationContext
in a web-enabled Spring framework (for
example, XmlWebApplicationContext
). If you use these scopes with regular Spring IoC containers such as
ClassPathXmlApplicationContext
, an IllegalStateException
will be thrown indicating the
bean's scope is unknown.
Initial web configuration
To support the creation of bean scope at the request
, session
, application
and
websocket
levels (web-scoped bins) requires some initial setup before defining a bin. (This initial
setup is not required for the standard scopes: singleton
and prototype
).
How you do this initial setup depends on your specific servlet environment.
If you access beans that are in scope in Spring Web MVC, that is, within a request that is handled by Spring DispatcherServlet
,
no special configuration is required. DispatcherServlet
already exposes all relevant states.
If you are using a Servlet 2.5 web container that handles requests outside of the Spring
DispatcherServlet
(for example, when using JSF or Struts), you need to register org.springframework.web.context.
request.RequestContextListener ServletRequestListener
. For Servlet 3.0+ this can be done programmatically
using the WebApplicationInitializer
interface. Alternatively, or for older versions of containers, add
the following declaration to your web application's web web.xml
file:
<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>
Alternatively, if you have trouble setting up the listener, consider using Spring's RequestContextFilter
.
The display of filters depends on the surrounding web application configuration, so you should change it
accordingly. The following listing shows part of a web application filter:
<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>
DispatcherServlet
, RequestContextListener
and RequestContextFilter
do the same
thing, namely associate an HTTP request object with a Thread
that serves this request. This allows
beans within the request or session scope to be accessed further down the call chain.
Request scope
Consider the following XML configuration to define a bean:
<bean id="loginAction" class="com.something.LoginAction" scope="request"/>
The Spring container creates a new instance of the LoginAction
bean using the loginAction
bean definition for each HTTP request. That is, the loginAction
bean is in scope at the HTTP request
level. You can change the internal state of the created instance as much as you like, since other instances created
from the same loginAction
bean definition do not see these state changes. They depend on the specific
request. If the request completes processing, the bean within the scope of the request is eliminated.
When using annotation-driven beans or Java configuration, the @RequestScope
annotation can be used to
assign the bean scope to request
. The following example shows how to do this:
@RequestScope
@Component
public class LoginAction {
// ...
}
@RequestScope
@Component
class LoginAction {
// ...
}
Visibility within a session
Consider the following XML configuration to define a bean:
<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>
The Spring container creates a new instance of the UserPreferences
bean using the
userPreferences
bean definition for the lifetime of one HTTP Session
. In other words, the
userPreferences
bean is effectively scoped at the HTTP Session
level. As with
request-scoped beans, you can modify the internal state of the created instance as much as you like, knowing that
other HTTP Session
instances that also use instances created based on the same bean definition userPreferences
will not notice these state changes because they pertain to a separate HTTP Session
. If an HTTP Session
ends up being excluded, the bean that is bound to that particular HTTP Session
is also excluded.
When using annotation-driven beans or Java configuration, you can use the @SessionScope
annotation to
assign a bean scope to session
.
@SessionScope
@Component
public class UserPreferences {
// ...
}
@SessionScope
@Component
class UserPreferences {
// ...
}
Visibility within the application
Consider the following XML configuration to define a bean:
<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>
The Spring container creates a new instance of the AppPreferences
bean using the
appPreferences
bean definition once for the entire web application. That is, the
appPreferences
bean is in scope at the ServletContext
level and is stored as a regular
ServletContext
attribute. It is somewhat similar to the Spring singleton bean, but differs from it in
two important ways: It is a singleton object for each ServletContext
, rather than for the Spring ApplicationContext
(which can be multiple in any given web application), and it actually opens, which is why it is visible as the
ServletContext
attribute.
When using annotation-driven beans or Java configuration, you can use the @ApplicationScope
annotation
to assign the bean scope to application
. The following example shows how to do this:
@ApplicationScope
@Component
public class AppPreferences {
// ...
}
@ApplicationScope
@Component
class AppPreferences {
// ...
}
Visibility scope within WebSocket
WebSocket scope is associated with the lifecycle of a WebSocket session and applies to STOMP over WebSocket applications.
GO TO FULL VERSION