当服务器接收到请求时,Tomcat会调用DispatcherServlet#doDispatch统一处理请求
java
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);
// 1.获取Handler处理器对象
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 2.获取对应的HandlerAdapter对象
HandlerAdapter ha = 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 (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
// 3.调用HandlerInterceptor前置处理请求
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 4.真正处理请求
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
// 5.调用HandlerInterceptor后置处理请求
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);
}
// 6.处理请求结果
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()) {
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
doDispatch的核心逻辑如下:
1.获取Handler处理器对象
遍历默认的(或配置在容器中的)handlerMappings,根据请求路径匹配某个HandlerMapping中的Handler,并封装成HandlerExecutionChain返回
2.获取对应的HandlerAdapter对象
遍历默认的(或配置在容器中的)handlerAdapters,根据HandlerAdpater接口中的supports方法判断该Handler能否被此handlerAdapter处理,如果可以处理即返回
java
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler +
"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
即不同的HandlerAdpater实现类可以处理不同类型的Handler,DispatcherServlet.properties中的默认配置是HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、RequestMappingHandlerAdapter及HandlerFunctionAdapter
1)HttpRequestHandlerAdapter能处理实现了HttpRequestHandler接口的Handler
java
public boolean supports(Object handler) {
return (handler instanceof HttpRequestHandler);
}
2)SimpleControllerHandlerAdapter能处理实现了Controller接口的Handler
java
public boolean supports(Object handler) {
return (handler instanceof Controller);
}
3)RequestMappingHandlerAdapter能处理HandlerMethod类型的Handler
java
public final boolean supports(Object handler) {
return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
}
protected boolean supportsInternal(HandlerMethod handlerMethod) {
return true;
}
4)HandlerFunctionAdapter能处理实现了HandlerFunction接口的Handler
java
public boolean supports(Object handler) {
return handler instanceof HandlerFunction;
}
3.调用HandlerInterceptor前置处理请求
获取Handler的过程中会将Handler对象封装为HandlerExecutionChain对象,其中包含了Handler和HandlerInterceptor两部分,HandlerInterceptor用于对处理器进行增强
HandlerInterceptor是如何添加进来的呢?我们看下AbstractHandlerMapping#initApplicationContext
java
protected void initApplicationContext() throws BeansException {
// 1.通过子类继承扩展
extendInterceptors(this.interceptors);
// 2.查找容器中的MappedInterceptor
detectMappedInterceptors(this.adaptedInterceptors);
// 3.将interceptors统一添加到adaptedInterceptors中
initInterceptors();
}
protected void extendInterceptors(List<Object> interceptors) {}
protected void detectMappedInterceptors(List<HandlerInterceptor> mappedInterceptors) {
mappedInterceptors.addAll(BeanFactoryUtils.beansOfTypeIncludingAncestors(
obtainApplicationContext(), MappedInterceptor.class, true, false).values());
}
protected void initInterceptors() {
if (!this.interceptors.isEmpty()) {
for (int i = 0; i < this.interceptors.size(); i++) {
Object interceptor = this.interceptors.get(i);
if (interceptor == null) {
throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null");
}
this.adaptedInterceptors.add(adaptInterceptor(interceptor));
}
}
}
AbstractHandlerMapping是所有默认HandlerMapping的父类,如下图所示:
因此这些HandlerMapping在初始化时都会调用到AbstractHandlerMapping的initApplicationContext注册HandlerInterceptor,从源码看出,注册方式有2种:1)自定义HandlerMapping子类重写extendInterceptors方法;2)在容器中添加HandlerInterceptor的组件
然后再获取Handler之后调用getHandlerExecutionChain将Handler和HandlerInterceptor封装成HandlerExecutionChain对象,源码如下:
java
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, LOOKUP_PATH);
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
// HandlerExecutionChain添加匹配的HandlerInterceptor
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
else {
chain.addInterceptor(interceptor);
}
}
return chain;
}
在步骤3中会依次执行这些HandlerInterceptor的preHandle做前置处理逻辑
4.调用HandlerAdapter的handle方法真正的处理请求
此时会调用HandlerAdapter的具体实现类去执行处理方法,这里以最常用的RequestMappingHandlerAdapter为例说明,源码见RequestMappingHandlerAdapter#handleInternal
java
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
checkRequest(request);
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
// 执行请求
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// 执行请求
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// 执行请求
mav = invokeHandlerMethod(request, response, handlerMethod);
}
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}
else {
prepareResponse(response);
}
}
return mav;
}
核心方法是调用RequestMappingHandlerAdapter#invokeHandlerMethod
java
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
// 创建ServletInvocableHandlerMethod,这个对象中聚合了执行方法需要的所有组件
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
if (this.argumentResolvers != null) {
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
if (this.returnValueHandlers != null) {
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);
// 省略部分代码...
// 执行处理器方法
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
// 返回ModelAndView
return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
// 标记请求处理完成
webRequest.requestCompleted();
}
}
在invokeHandlerMethod中,具体执行处理器方法的是ServletInvocableHandlerMethod对象,它需要添加一些组件配合完成请求的处理,这些组件分别有参数名称解析器、数据绑定工厂、参数解析器及返回值解析器
invocableMethod.invokeAndHandle执行控制器方法,源码如下:
java
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
// 调用控制器方法执行请求,获取响应对象
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
setResponseStatus(webRequest);
if (returnValue == null) {
if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
disableContentCachingIfNecessary(webRequest);
mavContainer.setRequestHandled(true);
return;
}
}
else if (StringUtils.hasText(getResponseStatusReason())) {
mavContainer.setRequestHandled(true);
return;
}
mavContainer.setRequestHandled(false);
Assert.state(this.returnValueHandlers != null, "No return value handlers");
try {
// 通过返回值处理器处理响应对象
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
catch (Exception ex) {
if (logger.isTraceEnabled()) {
logger.trace(formatErrorForReturnValue(returnValue), ex);
}
throw ex;
}
}
再通过invokeForRequest解析参数后,调用控制器方法执行请求
java
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
// 获取方法执行参数
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
logger.trace("Arguments: " + Arrays.toString(args));
}
// 真正反射执行目标方法
return doInvoke(args);
}
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
// 获取参数列表
MethodParameter[] parameters = getMethodParameters();
if (ObjectUtils.isEmpty(parameters)) {
return EMPTY_ARGS;
}
Object[] args = new Object[parameters.length];
// 逐个处理每个参数
for (int i = 0; i < parameters.length; i++) {
MethodParameter parameter = parameters[i];
// 初始化参数名称解析器
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
// 从给定参数中寻找,如果能匹配到就不通过参数解析器进行解析了
// providedArgs一般为空,invocableMethod.invokeAndHandle调用时可以传入一些参数
args[i] = findProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
// 判断参数解析器能够支持此参数,这里的参数解析器是HandlerMethodArgumentResolverComposite组合器,会依次匹配每个参数解析器
if (!this.resolvers.supportsParameter(parameter)) {
throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
}
try {
// 通过参数解析器解析参数
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
}
catch (Exception ex) {
if (logger.isDebugEnabled()) {
String exMsg = ex.getMessage();
if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {
logger.debug(formatArgumentError(parameter, exMsg));
}
}
throw ex;
}
}
return args;
}
最终调用doInvoke()通过方法反射调用目标控制器方法
java
protected Object doInvoke(Object... args) throws Exception {
// 如果不是public修饰的方法,则setAccessible(true)
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
// 通过方法反射调用,getBridgedMethod如果不是桥接的方法,返回的就是方法本身
return getBridgedMethod().invoke(getBean(), args);
}
// 省略异常处理代码...
}
5.调用HandlerInterceptor后置处理请求
与步骤3类似,此时会依次执行这些HandlerInterceptor的postHandle做后置处理逻辑
6.处理请求结果
处理请求结果时会先判断上述执行过程中是否出现异常,如果有异常,则处理异常,返回异常处理后的ModelAndView,然后再判断是否需要进行视图渲染
java
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
boolean errorView = false;
// 如果执行过程中有异常
if (exception != null) {
if (exception instanceof ModelAndViewDefiningException) {
logger.debug("ModelAndViewDefiningException encountered", exception);
mv = ((ModelAndViewDefiningException) exception).getModelAndView();
}
else {
Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
// 处理异常
mv = processHandlerException(request, response, handler, exception);
errorView = (mv != null);
}
}
if (mv != null && !mv.wasCleared()) {
// 如果需要渲染视图,则走mvc的流程
render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("No view rendering, null ModelAndView returned.");
}
}
if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
return;
}
if (mappedHandler != null) {
// 调用方法拦截器HandlerInterceptor的afterCompletion方法
mappedHandler.triggerAfterCompletion(request, response, null);
}
}