在该servlet初始化时,会 this.webApplicationContext = this.initWebApplicationContext();创建beanFactory和相应的bean,
所以对于springmvc项目,下面的listener与servlet只需要配置一个就行了,对于web项目,只需要配置servlet。
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
作为web应用的入口转发器,入口方法是
protected final void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
long startTime = System.currentTimeMillis();
Throwable failureCause = null;
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
LocaleContext localeContext = this.buildLocaleContext(request);
RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes requestAttributes = this.buildRequestAttributes(request, response, previousAttributes);
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new FrameworkServlet.RequestBindingInterceptor(null));
this.initContextHolders(request, localeContext, requestAttributes);
try {
this.doService(request, response);
} catch (ServletException var17) {
failureCause = var17;
throw var17;
} catch (IOException var18) {
failureCause = var18;
throw var18;
} catch (Throwable var19) {
failureCause = var19;
throw new NestedServletException("Request processing failed", var19);
} finally {
this.resetContextHolders(request, previousLocaleContext, previousAttributes);
if(requestAttributes != null) {
requestAttributes.requestCompleted();
}
if(this.logger.isDebugEnabled()) {
if(failureCause != null) {
this.logger.debug("Could not complete request", (Throwable)failureCause);
} else if(asyncManager.isConcurrentHandlingStarted()) {
this.logger.debug("Leaving response open for concurrent processing");
} else {
this.logger.debug("Successfully completed request");
}
}
this.publishRequestHandledEvent(request, response, startTime, (Throwable)failureCause);
}
}
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
if(this.logger.isDebugEnabled()) {
String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult()?" resumed":"";
this.logger.debug("DispatcherServlet with name '" + this.getServletName() + "'" + resumed + " processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]");
}
Map<String, Object> attributesSnapshot = null;
if(WebUtils.isIncludeRequest(request)) {
attributesSnapshot = new HashMap();
Enumeration attrNames = request.getAttributeNames();
label108:
while(true) {
String attrName;
do {
if(!attrNames.hasMoreElements()) {
break label108;
}
attrName = (String)attrNames.nextElement();
} while(!this.cleanupAfterInclude && !attrName.startsWith("org.springframework.web.servlet"));
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, this.getThemeSource());
FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if(inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
try {
this.doDispatch(request, response);
} finally {
if(!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted() && attributesSnapshot != null) {
this.restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
try {
ModelAndView mv = null;
Object dispatchException = null;
try {
processedRequest = this.checkMultipart(request); //判断是不是post表单请求,根据content-type判断
multipartRequestParsed = processedRequest != request;
//找到HandlerExecutionChain,里面包含有拦截器(已经筛选过路径),包含有目标Bean,目标方法。
mappedHandler = this.getHandler(processedRequest);
if(mappedHandler == null || mappedHandler.getHandler() == null) {
this.noHandlerFound(processedRequest, response);
return;
}
//(mappedHandler.getHandler()就是controller的执行方法,一个Method对象
//从handlerAdapters中找到一个支持这个handler的adapter
//这里获得的一般是RequestMappingHandlerAdapter。
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if(isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if(this.logger.isDebugEnabled()) {
this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
}
if(!mappedHandler.applyPreHandle(processedRequest, response)) {
//将org.springframework.web.servlet.resource.ResourceUrlProvider放到request中
//将org.springframework.core.convert.ConversionService放到request中
return;
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if(asyncManager.isConcurrentHandlingStarted()) {
return;
}
this.applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception var20) {
dispatchException = var20;
} catch (Throwable var21) {
dispatchException = new NestedServletException("Handler dispatch failed", var21);
}
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
} catch (Exception var22) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
} catch (Throwable var23) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
}
} finally {
if(asyncManager.isConcurrentHandlingStarted()) {
if(mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else if(multipartRequestParsed) {
this.cleanupMultipart(processedRequest);
}
}
}
handle方法
这个方法会调用controller层用户自定义的方法,然后返回modelAndView,所以主要流程都在这里。
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
this.checkRequest(request);
ModelAndView mav;
if(this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if(session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized(mutex) {
mav = this.invokeHandlerMethod(request, response, handlerMethod);
}
} else {
mav = this.invokeHandlerMethod(request, response, handlerMethod);
}
} else {
mav = this.invokeHandlerMethod(request, response, handlerMethod);
}
if(!response.containsHeader("Cache-Control")) {
if(this.getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
this.applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
} else {
this.prepareResponse(response);
}
}
return mav;
}
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response);
ModelAndView var15;
try {
WebDataBinderFactory binderFactory = this.getDataBinderFactory(handlerMethod);
ModelFactory modelFactory = this.getModelFactory(handlerMethod, binderFactory);
ServletInvocableHandlerMethod invocableMethod = this.createInvocableHandlerMethod(handlerMethod);
//把handlerMethod的核心信息提取出来到新创建对象invocableMethod
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
invocableMethod.setDataBinderFactory(binderFactory);
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
asyncWebRequest.setTimeout(this.asyncRequestTimeout);
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.setTaskExecutor(this.taskExecutor);
asyncManager.setAsyncWebRequest(asyncWebRequest);
asyncManager.registerCallableInterceptors(this.callableInterceptors);
asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
Object result;
if(asyncManager.hasConcurrentResult()) {
result = asyncManager.getConcurrentResult();
mavContainer = (ModelAndViewContainer)asyncManager.getConcurrentResultContext()[0];
asyncManager.clearConcurrentResult();
if(this.logger.isDebugEnabled()) {
this.logger.debug("Found concurrent result value [" + result + "]");
}
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
//重点,这里将会调用用户自定义的controller层的方法,也是浏览器请求路径对应的执行方法
invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]);
if(asyncManager.isConcurrentHandlingStarted()) {
result = null;
return (ModelAndView)result;
}
//执行完目标方法后,结果保存在mavContainer中,下面处理后获得modelAndView
var15 = this.getModelAndView(mavContainer, modelFactory, webRequest);
} finally {
webRequest.requestCompleted();
}
return var15;
}
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs);
this.setResponseStatus(webRequest);
if(returnValue == null) {
if(this.isRequestNotModified(webRequest) || this.getResponseStatus() != null || mavContainer.isRequestHandled()) {
mavContainer.setRequestHandled(true);
return;
}
} else if(StringUtils.hasText(this.getResponseStatusReason())) {
mavContainer.setRequestHandled(true);
return;
}
mavContainer.setRequestHandled(false);
try {//处理返回的结果
this.returnValueHandlers.handleReturnValue(returnValue, this.getReturnValueType(returnValue), mavContainer, webRequest);
} catch (Exception var6) {
if(this.logger.isTraceEnabled()) {
this.logger.trace(this.getReturnValueHandlingErrorMessage("Error handling return value", returnValue), var6);
}
throw var6;
}
}
public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
//获取目标方法的参数值
Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);
if(this.logger.isTraceEnabled()) {
this.logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(this.getMethod(), this.getBeanType()) + "' with arguments " + Arrays.toString(args));
}
Object returnValue = this.doInvoke(args);
if(this.logger.isTraceEnabled()) {
this.logger.trace("Method [" + ClassUtils.getQualifiedMethodName(this.getMethod(), this.getBeanType()) + "] returned [" + returnValue + "]");
}
//目标方法的返回值
return returnValue;
}
处理方法返回值的解析器
解析结果视图
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {
boolean errorView = false;
if(exception != null) {
if(exception instanceof ModelAndViewDefiningException) {
this.logger.debug("ModelAndViewDefiningException encountered", exception);
mv = ((ModelAndViewDefiningException)exception).getModelAndView();
} else {
Object handler = mappedHandler != null?mappedHandler.getHandler():null;
mv = this.processHandlerException(request, response, handler, exception);
errorView = mv != null;
}
}
if(mv != null && !mv.wasCleared()) {
this.render(mv, request, response);// 这里解析结果视图
if(errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
} else if(this.logger.isDebugEnabled()) {
this.logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + this.getServletName() + "': assuming HandlerAdapter completed request handling");
}
if(!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
if(mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
}
}
}
遍历所有的ViewResolver,知道找到一个能够解析的。
protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale, HttpServletRequest request) throws Exception {
Iterator var5 = this.viewResolvers.iterator();
View view;
do {
if(!var5.hasNext()) {
return null;
}
ViewResolver viewResolver = (ViewResolver)var5.next();
view = viewResolver.resolveViewName(viewName, locale);
} while(view == null);
return view;
}
HandlerMethodArgumentResolver
RequestParamMethodArgumentResolver解析方法的入口参数值
getLocal方法,获取浏览器支持的语言。
public Locale resolveLocale(HttpServletRequest request) {
Locale defaultLocale = this.getDefaultLocale();
if(defaultLocale != null && request.getHeader("Accept-Language") == null) {
return defaultLocale;
} else {
Locale requestLocale = request.getLocale();
if(this.isSupportedLocale(requestLocale)) {
return requestLocale;
} else {
Locale supportedLocale = this.findSupportedLocale(request);
return supportedLocale != null?supportedLocale:(defaultLocale != null?defaultLocale:requestLocale);
}
}
}
getHandlerExecutionChain方法
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain = handler instanceof HandlerExecutionChain?(HandlerExecutionChain)handler:new HandlerExecutionChain(handler);
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
Iterator var5 = this.adaptedInterceptors.iterator();//adaptedInterceptors是HandlerInterceptor的集合
while(var5.hasNext()) {
HandlerInterceptor interceptor = (HandlerInterceptor)var5.next();
if(interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor)interceptor;
if(mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
//筛选出符合当前请求的拦截器,交给handlerExecutionChain链,如果这个拦截器是MappedInterceptor的实例的话
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
} else {
//如果不是,则直接交给拦截链
chain.addInterceptor(interceptor);
}
}
return chain;
}
默认有3个handlerAdapter,
默认的handlerInterceptor
getDataBinderFactory方法
InitBinder.class注解,用在方法上。
WebDataBinderFactory 中包含有initBinder注解的方法
private WebDataBinderFactory getDataBinderFactory(HandlerMethod handlerMethod) throws Exception {
Class<?> handlerType = handlerMethod.getBeanType();
Set<Method> methods = (Set)this.initBinderCache.get(handlerType);
if(methods == null) {//methods保存的是类中具有InitBinder注解的方法,
methods = MethodIntrospector.selectMethods(handlerType, INIT_BINDER_METHODS);
this.initBinderCache.put(handlerType, methods);
}
List<InvocableHandlerMethod> initBinderMethods = new ArrayList();
Iterator var5 = this.initBinderAdviceCache.entrySet().iterator();
//Map<ControllerAdviceBean, Set<Method>> initBinderAdviceCache = new LinkedHashMap()
while(true) {
Entry entry;
Object bean;
do {
if(!var5.hasNext()) {//没有
var5 = methods.iterator();
while(var5.hasNext()) {
Method method = (Method)var5.next();
bean = handlerMethod.getBean();
initBinderMethods.add(this.createInitBinderMethod(bean, method));
}
return this.createDataBinderFactory(initBinderMethods);
}
entry = (Entry)var5.next();
} while(!((ControllerAdviceBean)entry.getKey()).isApplicableToBeanType(handlerType));
bean = ((ControllerAdviceBean)entry.getKey()).resolveBean();
Iterator var8 = ((Set)entry.getValue()).iterator();
while(var8.hasNext()) {
Method method = (Method)var8.next();
initBinderMethods.add(this.createInitBinderMethod(bean, method));
}
}
}
最后
以上就是健康冰棍为你收集整理的springmvc--DispatcherServlet的全部内容,希望文章能够帮你解决springmvc--DispatcherServlet所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复