请求时如何找到具体的Controller的方法的
- doGet等是如何而来
FrameworkServlet继承于HttpServletBean,HttpServletBean继承于HttpServlet - doGet、doPost、doPut、doDelete等http请求均会调用processRequest
FrameworkServlet部分相关源码如下:
@Override
protected final void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
...
doService(request, response);
...
}
- processRequest调用DispatcherServlet的doService
- doService调用doDispatch
- doDispatch调用applyPreHandle,执行所有HandlerInterceptor拦截器的preHandle方法
- doDispatch中代码mv = ha.handle(processedRequest, response, mappedHandler.getHandler());调用Controller的方法,如何调用,后面指出
- doDispatch调用applyPostHandle,执行所有HandlerInterceptor拦截器的postHandle方法
- doDispatch调用processDispatchResult
- processDispatchResult调用triggerAfterCompletion
- triggerAfterCompletion方法执行所有HandlerInterceptor拦截器的afterCompletion方法
- DispatcherServlet部分相关源码如下
protected void initStrategies(ApplicationContext context) {
...
this.initHandlerMappings(context);
this.initHandlerAdapters(context);
...
}
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
try {
this.doDispatch(request, response);
}
...
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
this.applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
...
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
...
}
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
}
return true;
}
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
HandlerInterceptor[] interceptors = this.getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for(int i = interceptors.length - 1; i >= 0; --i) {
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(request, response, this.handler, mv);
}
}
}
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception {
...
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
}
}
}
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) throws Exception {
...
interceptor.afterCompletion(request, response, this.handler, ex);
...
}
doDispatch中代码mv = ha.handle(processedRequest, response, mappedHandler.getHandler());调用Controller的方法
- ha为HandlerAdapter接口
- 具体实现使用RequestMappingHandlerAdapter
- RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
//AbstractHandlerMethodAdapter的方法
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return this.handleInternal(request, response, (HandlerMethod)handler);
}
@Nullable
protected abstract ModelAndView handleInternal(HttpServletRequest var1, HttpServletResponse var2, HandlerMethod var3) throws Exception;
- 之后调用handleInternal的抽象方法(实际调用RequestMappingHandlerAdapter的handleInternal),内部再次调用invokeHandlerMethod方法
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);
}
...
}
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
...
ServletInvocableHandlerMethod invocableMethod = this.createInvocableHandlerMethod(handlerMethod);
...
invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]);
...
}
- 在此调用 invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]);(ServletInvocableHandlerMethod类)
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs);
...
}
@Nullable
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Arguments: " + Arrays.toString(args));
}
return this.doInvoke(args);
}
- 调用invokeForRequest,再调用doInvoke
@Nullable
protected Object doInvoke(Object... args) throws Exception {
ReflectionUtils.makeAccessible(this.getBridgedMethod());
try {
return this.getBridgedMethod().invoke(this.getBean(), args);
...
- 使用return this.getBridgedMethod().invoke(this.getBean(), args);将controller对应,并传递参数(modelFactory.initModel(webRequest, mavContainer, invocableMethod); //参数通过此传递进入invocableMethod)
controller是从哪里找到的,是在handlerMethod中传递过来的。最早在doDispatch中
HandlerInterceptor拦截器的说明
public interface HandlerInterceptor {
//进入controller前进行判断,如果此处放回false,则直接返回
//用途:如token的验证
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
//controller执行方法返回后执行此操作
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
//执行操作返回前进入到此方法,可以对其进行加工等
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
参考
- https://www.cnblogs.com/fangjian0423/p/springMVC-request-mapping.html#reference
- https://blog.csdn.net/sunsiwenvip/article/details/80230050