初始化
spring boot下初始化配置类:org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration
spring boot 初始化时会扫描META-INF/spring.factories配置文件中配置的类,进行初始化
关注一下几个初始化类:
@Bean
@Override
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter();
adapter.setIgnoreDefaultModelOnRedirect(this.mvcProperties == null ? true
: this.mvcProperties.isIgnoreDefaultModelOnRedirect());
return adapter;
}
@Override(这里去个性化RequestMappingHandlerAdapter, 可以看到是从mvcRegistrations获取得)
(mvcRegistrations就是WebMvcRegistrations)
protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
if (this.mvcRegistrations != null
&& this.mvcRegistrations.getRequestMappingHandlerAdapter() != null) {
return this.mvcRegistrations.getRequestMappingHandlerAdapter();
}
return super.createRequestMappingHandlerAdapter();
}
@Bean
@Primary
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
// Must be @Primary for MvcUriComponentsBuilder to work
return super.requestMappingHandlerMapping();
}
如果需要个性化加入参数解析器HandlerMethodArgumentResolver或者出参解析器HandlerMethodReturnValueHandler,可以继承来实现,这两个都是RequestMappingHandlerAdapter 的成员变量
org.springframework.boot.autoconfigure.web.WebMvcRegistrations
或者
org.springframework.boot.autoconfigure.web.WebMvcRegistrationsAdapter
RequestMappingInfo初始化
HandlerInterceptor初始化
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.EnableWebMvcConfiguration#requestMappingHandlerMapping
==>
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerMapping
==>
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getInterceptors
==>
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#addInterceptors
==>
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#setConfigurers
==>
实现 org.springframework.web.servlet.config.annotation.WebMvcConfigurer接口
最终在RequestMappingHandlerMapping 完成org.springframework.web.servlet.handler.AbstractHandlerMapping#interceptors的初始化
DispatcherServlet在处理时,会获取这里的interceptors放到HandlerExecutionChain 中
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerMapping
DispatcherServlet之doDispatch
看一下spring HTTP请求最主要的方法:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// Determine handler for the current request.
//这个获取的HandlerExecutionChain,里面的handler是通过
//org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#getHandlerInternal 获取的
//并且handler是HandlerMethod的实现类
//主要获取逻辑就是利用RequestCondition去匹配查找,或者直接从mappingRegistry直接映射获取
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// Determine handler adapter for the current request.
//这里获取HandlerAdapter,大部分情况下就是初始化部分的RequestMappingHandlerAdapter
//判断依据:org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#supports
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
// As of 4.3, we're processing Errors thrown from handler methods as well,
// making them available for @ExceptionHandler methods and other scenarios.
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}