SpringMVC请求执行全流程源码解析
本文将通过源码阅读,解析请求在SpringMVC中的处理流程,包括DispatcherServlet的初始化,查找处理器,查找映射器等流程。阅读本文前最好先读一下之前写的前置文章,才能更好的理解一些全局变量是如何初始化并赋值的。可以先阅读以下文章:
SpringMVC HandlerMapping(处理器映射器)常用实现类源码详解
RequestMappingHandlerAdapter源码解析
SpringMVC自动配置类避坑及源码详解
前置概念
父子容器概念
Spring会创建一个WebApplicationContext上下文,称为父上下文(父容器) ,保存在 ServletContext中, key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值。可以使用Spring提供的工具类取出上下文对象:WebApplicationContextUtils.getWebApplicationContext(ServletContext);
DispatcherServlet是一个Servlet,可以同时配置多个,每个 DispatcherServlet有一个自己的上下文对象(WebApplicationContext),称为子上下文(子容器),子上下文可以访问父上下文中的内容,但父上下文不能访问子上下文中的内容。 它也保存在 ServletContext中,key是"org.springframework.web.servlet.FrameworkServlet.CONTEXT"+Servlet名称。当一个Request对象产生时,会把这个子上下文对象(WebApplicationContext)保存在Request对象中,key是DispatcherServlet.class.getName() + “.CONTEXT”。 可以使用工具类取出上下文对象:RequestContextUtils.getWebApplicationContext(request);
所以在Controller中注入Service和Dao对象是可以的,但是反过来是不可以的,因为Service和Dao的对象是存放在父容器中的,而Controller是在子容器中的。
springMVC核心过滤器DispatcherServlet
Servlet初始化时机是在项目启动后,第一次请求过来的时候进行初始化的,DispatcherServlet就是第一次请求过来的时候初始化的。
在springboot中核心过滤器的自动创建是由自动配置类DispatcherServletAutoConfiguration进行创建和注册的,代码如下:
//创建dispatcherServlet
@Bean(name = {"dispatcherServlet"})
public DispatcherServlet dispatcherServlet() {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.setDispatchOptionsRequest(this.webMvcProperties.isDispatchOptionsRequest());
dispatcherServlet.setDispatchTraceRequest(this.webMvcProperties.isDispatchTraceRequest());
dispatcherServlet.setThrowExceptionIfNoHandlerFound(this.webMvcProperties.isThrowExceptionIfNoHandlerFound());
return dispatcherServlet;
}
//注册servlet
@Bean(name = {"dispatcherServletRegistration"})
@ConditionalOnBean(value = {DispatcherServlet.class},name = {"dispatcherServlet"})
public ServletRegistrationBean<DispatcherServlet> dispatcherServletRegistration(DispatcherServlet dispatcherServlet) {
ServletRegistrationBean<DispatcherServlet> registration = new ServletRegistrationBean(dispatcherServlet, new String[]{this.serverProperties.getServlet().getServletMapping()});
registration.setName("dispatcherServlet");
registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup());
if (this.multipartConfig != null) {
registration.setMultipartConfig(this.multipartConfig);
}
return registration;
}
DispatcherServlet类的源码解析
初始化过程
DispatcherServlet就是第一次请求过来的时候初始化的
DispatcherServlet初始化方法,从容器中获取到接口实现类,存储在类的全局变量中。接口实现类在项目启动的时候已经注入到了容器中。
protected void initStrategies(ApplicationContext context) {
//初始化文件上传解析器 -->MultipartResolver 接口
initMultipartResolver(context);
//初始化国际化相关解析器 -->LocaleResolver 接口
initLocaleResolver(context);
//初始化主题样式解析器 -->ThemeResolver 接口
initThemeResolver(context);
//初始化处理器映射器 -->HandlerMapping 接口
//RequestMappingHandlerMapping SimpleUrlHandlerMapping BeanNameUrlHandlerMapping
initHandlerMappings(context);
//初始化处理器适配器 -->HandlerAdapter 接口
initHandlerAdapters(context);
//初始化异常解析器 -->HandlerExceptionResolver 接口
initHandlerExceptionResolvers(context);
// RequestToViewNameTranslator接口
initRequestToViewNameTranslator(context);
//初始化视图解析器 --> ViewResolver 接口
initViewResolvers(context);
//初始化重定向参数管理器 --> FlashMapManager 接口
initFlashMapManager(context);
}
请求处理流程
请求入口
Servlet接口规范所有的请求都是走Servlet的service方法。抽象类HttpServlet实现了该接口,再此基础上衍生出根据不同请求方式分发请求到不同的方法。如doGet doPost doPut等几个方法
上图中,可以看出DispatcherServlet继承了并重写了上述方法,最终又全部交个processRequest方法处理,该方法省略后部分代码如下:
protected final void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//......省略代码
try {
doService(request, response);
}catch (Exception ex) {
throw ex;
}finally {
//.....省略代码
//发布处理事件
publishRequestHandledEvent(request, response, startTime, failureCause);
}
}
处理请求的核心逻辑由doService方法实现,这个是交个子类实现, DispatcherServlet继承并实现了该方法。
在请求处理完成的最后,发布了一个请求被处理的事件,事件代码如下:
private void publishRequestHandledEvent(HttpServletRequest request, HttpServletResponse response,
long startTime, @Nullable Throwable failureCause) {
if (this.publishEvents && this.webApplicationContext != null) {
// Whether or not we succeeded, publish an event.
long processingTime = System.currentTimeMillis() - startTime;
this.webApplicationContext.publishEvent(
new ServletRequestHandledEvent(this,
request.getRequestURI(), request.getRemoteAddr(),
request.getMethod(), getServletConfig().getServletName(),
WebUtils.getSessionId(request), getUsernameForRequest(request),
processingTime, failureCause, response.getStatus()));
}
}
该事件收集了请求的所有信息,应用层面可以通过监听该事件进行对不同接口请求的信息统计,然后根据统计信息做一下接口并发限制或者降级逻辑。
DispatcherServlet处理方法doService
这个方法进行简单的处理,将请求绑定一些相关组件进行资源处理和解析。
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
//判断是否是include的页面请求,并将include的请求相关参数复制一份进行存储
Map<String, Object> attributesSnapshot = null;
if (WebUtils.isIncludeRequest(request)) {
attributesSnapshot = new HashMap<>();
Enumeration<?> attrNames = request.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = (String) attrNames.nextElement();
if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
}
//这里绑定的key都关联到了对应的Servlet,因为每一个Servlet都需要一个上下文容器
//将请求绑定springMVC上下文容器,也就是所谓的子容器
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());
//flushMap解决重定向传参问题
if (this.flashMapManager != null) {
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 {
//核心分发方法
doDispatch(request, response);
}finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
}
DispatcherServlet处理请求的核心流程
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 {
//通过contentType判断是不是文件上传的请求,然后将请求转换成StandardMultipartHttpServletRequest
processedRequest = checkMultipart(request);
//通过判断request是否被转换过,修改是否文件上传的请求标记
multipartRequestParsed = (processedRequest != request);
//获取当前请求对应的处理器执行链
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
//获取处理器适配器(三种类型中的一种)
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
//处理last-modified请求头(如果处理器支持)
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;
}
}
//调用拦截器的preHandle方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//调用处理器(controller)的方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//如果异步任务已经开始,则直接返回
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
//使用默认的视图名称
applyDefaultViewName(processedRequest, mv);
//调用拦截器的postHandle方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
}catch (Exception ex) {
dispatchException = ex;
}
//处理分发结果:例如处理异常,清除资源,最后调用拦截器的afterCompletion方法
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}catch (Exception ex) {
//回调拦截器的afterCompletion方法
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}finally {
//判断是否是异步请求方式并且已经请求已经开始处理了
if (asyncManager.isConcurrentHandlingStarted()) {
//调用异步处理拦截器的afterConcurrentHandlingStarted方法,替换拦截器的postHandle和afterCompletion方法
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}else {
//multipart文件下载类请求清除资源
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
获取处理器执行链
1. 获取处理器映射器,用于获取处理器执行链
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//该类实例化的时候收集了所有的处理器映射器,可查看构造方法
if (this.handlerMappings != null) {
for (HandlerMapping hm : this.handlerMappings) {
//通过处理器映射器构建并拿到对应的处理器执行链
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
2.通过映射器获取处理器和拦截器封装成处理器执行链
AbstractHandlerMapping的getHandler方法
@Nullable
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//从request中拿到请求的uri-->从MappingRegistry.urlLookup中获取到RequestMappingInfo
//-->再从从MappingRegistry.mappingLookup 拿到HandlerMethod进行匹配后并返回
Object handler = getHandlerInternal(request); //这里会执行RequestCondition.getMatchingCondition方法
//找不到则使用默认的
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
//获取执行器链,并将所有的拦截器封装到执行器链路中
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
//跨域请求处理,将跨域配置封装到拦截器然后再封装到执行器链路
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
//将handler封装到执行器链
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
else {
chain.addInterceptor(interceptor);
}
}
return chain;
}
3.获取处理器的流程
getHandlerInternal(request)获取处理器的细节方法,主要思路就是:
- 从request中拿到请求的uri–>从MappingRegistry.urlLookup中获取到RequestMappingInfo
- 再从从MappingRegistry.mappingLookup 拿到HandlerMethod进行匹配后并返回
MappingRegistry类封装了所有处理器的信息,不清楚的请阅读我这篇文章:
SpringMVC HandlerMapping(处理器映射器)常用实现类源码详解中的RequestMappingHandlerMapping初始化过程源码解析一节。
源码流程如下:
3.1 获取请求uri
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
//从请求中解析获取到请求的uri,这个uri包括项目路径和servlet的path
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
if (logger.isDebugEnabled()) {
logger.debug("Looking up handler method for path " + lookupPath);
}
this.mappingRegistry.acquireReadLock();
try {
//通过请求参数和路径查找处理器
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
//....省略日志代码
//复制处理器信息,构建新的返回(如果拿到是Bean名字,先从容器中获取再复制)
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
this.mappingRegistry.releaseReadLock();
}
}
3.2 通过请求参数和路径查找处理器
@Nullable
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
List<Match> matches = new ArrayList<>();
//获取同一个uri映射的接口方法信息RequestMappingInfo
List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
if (directPathMatches != null) {
//变量拿到的集合信息,重新封装到一个新的RequestMappingInfo对象,存到到matches中
//这里调用了自定义的RequestCondition接口getMatchingCondition方法
addMatchingMappings(directPathMatches, matches, request);
}
if (matches.isEmpty()) {
//遍历所有的处理器映射器获取匹配的处理器方法
addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
}
if (!matches.isEmpty()) {
//构建比较器
Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
matches.sort(comparator);
if (logger.isTraceEnabled()) {
logger.trace("...." + matches);
}
Match bestMatch = matches.get(0);
//如果找到多个处理器方法(自定义才可能出现的情况)
if (matches.size() > 1) {
if (CorsUtils.isPreFlightRequest(request)) {
return PREFLIGHT_AMBIGUOUS_MATCH;
}
//只是比较前两个
Match secondBestMatch = matches.get(1);
//调用自定义的RequestCondition接口compareTo方法
if (comparator.compare(bestMatch, secondBestMatch) == 0) {
Method m1 = bestMatch.handlerMethod.getMethod();
Method m2 = secondBestMatch.handlerMethod.getMethod();
throw new IllegalStateException("....." );
}
}
//将请求路径封存放到request域对象中
handleMatch(bestMatch.mapping, lookupPath, request);
//返回处理器
return bestMatch.handlerMethod;
}
else {
return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
}
}
获取处理器适配器
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter ha : this.handlerAdapters) {
if (logger.isTraceEnabled()) {
logger.trace(".....");
}
//获取处理器适配器(三种类型中的一种)
if (ha.supports(handler)) {
return ha;
}
}
}
throw new ServletException(".....");
}
调用处理器(Controller)方法
跟踪handle方法,可以发现,调用处理器方法的逻辑最终实现是在处理器适配器RequestMappingHandlerAdapter的handleInternal方法中实现的。查看该方法代码如下:
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
//检查请求是否符合要求
checkRequest(request);
//判断执行处理器方法是否需要在session上窜行,默认否
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
//使用互斥锁
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}else {
//没有session,不需要互斥锁,执行处理器方法
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}else {
//执行处理器方法
mav = invokeHandlerMethod(request, response, handlerMethod);
}
//判断处理Cache-Control请求头,根据条件设置响应请求头
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}else {
//准备Cache-Control请求头,设置缓存时间
prepareResponse(response);
}
}
return mav;
}
反射调用Controller方法
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
//将@InitBinder注解标记方法封装到工厂类中
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
//将@ModelAttribute注解标记的方法封装到工厂类中
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
//创建调用方法对象,并封装对应的解析类
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);
//处理异步的相关参数和组件
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);
if (asyncManager.hasConcurrentResult()) {
Object result = asyncManager.getConcurrentResult();
mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
asyncManager.clearConcurrentResult();
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
//反射调用处理器方法
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
webRequest.requestCompleted();
}
}
//反射调用处理器方法
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()) {
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 {
//选择一个匹配的返回值处理器HandlerMethodReturnValueHandler处理返回值,写回响应
//调用handleReturnValue方法,默认自定义的组件排在系统组件之后
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}catch (Exception ex) {
throw ex;
}
}
@Nullable
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//调用参数解析器解析方法入参
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
"' with arguments " + Arrays.toString(args));
}
//反射调用controller方法
Object returnValue = doInvoke(args);
if (logger.isTraceEnabled()) {
logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
"] returned [" + returnValue + "]");
}
return returnValue;
}
/**
* 对当前方法入参进行解析
*/
private Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//获取调用Controller方法的所有参数列表
MethodParameter[] parameters = getMethodParameters();
Object[] args = new Object[parameters.length];
//循环对参数进行解析赋值和校验
for (int i = 0; i < parameters.length; i++) {
MethodParameter parameter = parameters[i];
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
//从一系列提供的参数中解析,视图相关
args[i] = resolveProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
//循环遍历所有的参数解析器,判断是否有支持该参数解析的方式
//调用扩展接口HandlerMethodArgumentResolver.supportsParameter方法
if (this.argumentResolvers.supportsParameter(parameter)) {
try {
//获取扩展接口HandlerMethodArgumentResolver对应实例,调用resolveArgument方法解析参数
args[i] = this.argumentResolvers.resolveArgument(
parameter, mavContainer, request, this.dataBinderFactory);
continue;
}catch (Exception ex) {
throw ex;
}
}
if (args[i] == null) {
throw new IllegalStateException("....");
}
}
return args;
}
总结
调用逻辑总体上是,获取并组装处理器信息,然后获取适配器,通过适配器调用参数解析器组装入参,之后反射调用处理器的方法,最后通过返回值处理器,视图解析器等组件处理响应。
现在流行restful接口,前后端分离形式,点击阅读这篇文章关于@RequestBody @ResponseBody 注解处理的类RequestResponseBodyMethodProcessor 。同时负责参数解析和返回值解析。