简介
使用SpringMVC作为web应用的框架是一般都会涉及Request,Session等,RequestContextListener就是为此定义的。
详解
首先分清web容器和Spring容器的区别,这是两个东西,Web容器表示装载,执行和处理web应用的容器,比如Tomcat,Jetty等,而Spring容器则是BeanFactory,applicationContext,WebApplicationContext等。
在此之前讨论了ContextLoaderListener监听器的作用,它是针对web容器(Tomcat或Jetty等)的启动和关闭行为,在web容器启动时会通过事件获取ServletContext,同时初始化WebApplicationContext并把ServletContext实例注入到WebApplicationContext当中。
这里讨论的RequestContextListener则是监听客户端对web应用的每一个请求,当每一个请求到达的时候都会触发这个监听器执行,从源码可知它主要是获取当前请求实例并且将实例注入到一些公用的实例当中,我当前的猜想是,这些实例应该会被框架其他部分调用。
web应用在定义bean的时候有一个作用域的概念,主要有:singleton(默认),Propertype,还有WebApplicationContext独有的Request,Session,GlobalSession,具体有什么区别去查。如果Spring的Bean需要用到Request,Session,GlobalSession作用域就必须进行配置,目前知道的有两种方法
第一:低版本web容器
<filter>
<filter-name>RequestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RequestContextFilter</filter-name>
<servlet-name>/*</servlet-name>
</filter-mapping>
第二:高版本web容器
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
RequestContextListener监听器源码:
public class RequestContextListener implements ServletRequestListener {
private static final String REQUEST_ATTRIBUTES_ATTRIBUTE =
RequestContextListener.class.getName() + ".REQUEST_ATTRIBUTES";
@Override
public void requestInitialized(ServletRequestEvent requestEvent) {
if (!(requestEvent.getServletRequest() instanceof HttpServletRequest)) {
throw new IllegalArgumentException(
"Request is not an HttpServletRequest: " + requestEvent.getServletRequest());
}
HttpServletRequest request = (HttpServletRequest) requestEvent.getServletRequest();
ServletRequestAttributes attributes = new ServletRequestAttributes(request);
request.setAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE, attributes);
LocaleContextHolder.setLocale(request.getLocale());
RequestContextHolder.setRequestAttributes(attributes);
}
@Override
public void requestDestroyed(ServletRequestEvent requestEvent) {
ServletRequestAttributes attributes = null;
Object reqAttr = requestEvent.getServletRequest().getAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE);
if (reqAttr instanceof ServletRequestAttributes) {
attributes = (ServletRequestAttributes) reqAttr;
}
RequestAttributes threadAttributes = RequestContextHolder.getRequestAttributes();
if (threadAttributes != null) {
// We're assumably within the original request thread...
LocaleContextHolder.resetLocaleContext();
RequestContextHolder.resetRequestAttributes();
if (attributes == null && threadAttributes instanceof ServletRequestAttributes) {
attributes = (ServletRequestAttributes) threadAttributes;
}
}
if (attributes != null) {
attributes.requestCompleted();
}
}
}