在SpringMVC中我们无需显示的获取Request,Session等对象而可以进行直接获取使用
重要的接口和类:
public interface RequestAttributes {
int SCOPE_REQUEST = 0;
int SCOPE_SESSION = 1;
int SCOPE_GLOBAL_SESSION = 2;
String REFERENCE_REQUEST = "request";
String REFERENCE_SESSION = "session";
Object getAttribute(String name, int scope);
void setAttribute(String name, Object value, int scope);
void removeAttribute(String name, int scope);
String[] getAttributeNames(int scope);
String getSessionId();
......
}
public abstract class RequestContextHolder {
private static final ThreadLocal<RequestAttributes> requestAttributesHolder =new NamedThreadLocal<RequestAttributes>("Request attributes");
private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder =new NamedInheritableThreadLocal<RequestAttributes>("Request context");
public static void resetRequestAttributes() {
requestAttributesHolder.remove();
inheritableRequestAttributesHolder.remove();
}
public static void setRequestAttributes(RequestAttributes attributes) {
setRequestAttributes(attributes, false);
}
public static RequestAttributes getRequestAttributes() {
RequestAttributes attributes = requestAttributesHolder.get();
if (attributes == null) {
attributes = inheritableRequestAttributesHolder.get();
}
return attributes;
}
.....
}
上面的类主要是把状态域对象用ThreadLocal来保存。在以前我们service层要想使用域对象必须先从Controller层中获取再传递过去。现在SpringMVC框架已经在procesRequest做了封装。它会将当前的request对象和session对象封装到框架中。RequestAttributes previousRequestAttributes = RequestContextHolder.getRequestAttributes();和if (previousRequestAttributes == null || previousRequestAttributes.getClass().equals(ServletRequestAttributes.class)) {
requestAttributes = new ServletRequestAttributes(request);
RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable);
}就是对其进行设计。而我们的servic层实在processRequest之后调用的所以我们可以直接获取
主要流程及调用类:
FrameworkServlet中的processRequest
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
LocaleContextHolder.setLocaleContext(buildLocaleContext(request), this.threadContextInheritable);
RequestAttributes previousRequestAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes requestAttributes = null;
if (previousRequestAttributes == null || previousRequestAttributes.getClass().equals(ServletRequestAttributes.class)) {
requestAttributes = new ServletRequestAttributes(request);
RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable);
}
doService(request, response);
LocaleContextHolder.setLocaleContext(previousLocaleContext, this.threadContextInheritable);
if (requestAttributes != null) {
RequestContextHolder.setRequestAttributes(previousRequestAttributes, this.threadContextInheritable);
requestAttributes.requestCompleted();
}
DispatchServlet中的doService
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
doDispatch(request, response);
DispatchServlet中的doDispatch方法
ModelAndView mv;
HandlerExecutionChain mappedHandler = null;
processedRequest = checkMultipart(request);
mappedHandler = getHandler(processedRequest, false);
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
if (interceptors != null) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
return;
}
interceptorIndex = i;
}
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
mv.setViewName(getDefaultViewName(request));
if (interceptors != null) {
for (int i = interceptors.length - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);
}
}
render(mv, processedRequest, response);
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);