1.springmvc中RequestMappingHandlerAdapter继承体系
2.概述
首先,RequestMappingHandlerAdapter实现了InitializingBean接口。
bean初始化时会调用afterPropertiesSet方法来处理加了ControllerAdvice注解的类
加载HandlerMethodArgumentResolver参数解析器处理参数
加载处理InitBinder的HandlerMethodArgumentResolver参数解析器
加载HandlerMethodReturnValueHandler返回值处理程序处理返回值。
之后就是重写了HandlerAdapter的supportsInternal方法来判断次适配器是否支持处理HandlerMethod类型的处理器,这里是支持。
重写了HandlerAdapter的handle方法来处理请求
3.RequestMappingHandlerMapping整个代码用工具翻译后的
https://blog.csdn.net/qq_39482039/article/details/120257541
4.初始化流程分析
RequestMappingHandlerAdapter实现了InitializingBean接口,bean初始化时会调用afterPropertiesSet方法。
@Override
public void afterPropertiesSet() {
// 首先这样做,它可能会添加 ResponseBody 建议 bean
//加载加了ControllerAdvice注解的类
initControllerAdviceCache();
//参数解析为空,加载默认的参数解析类
if (this.argumentResolvers == null) {
List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
//参数解析为空,加载默认的初始化参数绑定类
if (this.initBinderArgumentResolvers == null) {
List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
//如果返回值处理属性为空,加载默认的返回值处理类
if (this.returnValueHandlers == null) {
List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
}
}
initControllerAdviceCache方法
从web上下文中查找加了ControllerAdvice注解的bean
查找bean中没有加RequestMapping注解,加了ModelAttribute注解的方法,设置到属性 modelAttributeAdviceCache
查找加了InitBinder的方法,设置到属性initBinderAdviceCache
查找父类是RequestBodyAdvice或ResponseBodyAdvice的类,设置到属性 requestResponseBodyAdvice
private void initControllerAdviceCache() {
if (getApplicationContext() == null) {
return;
}
//处理加了ControllerAdvice注解的类
List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
List<Object> requestResponseBodyAdviceBeans = new ArrayList<>();
for (ControllerAdviceBean adviceBean : adviceBeans) {
Class<?> beanType = adviceBean.getBeanType();
if (beanType == null) {
throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
}
//查找bean中没有加RequestMapping注解,加了ModelAttribute注解的方法
Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
if (!attrMethods.isEmpty()) {
//缓存加了ModelAttribute方法
this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
}
//查找bean中加了InitBinder注解的方法
Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
if (!binderMethods.isEmpty()) {
//缓存ModelAttribute注解的方法
this.initBinderAdviceCache.put(adviceBean, binderMethods);
}
//bean类型的父类是RequestBodyAdvice或者ResponseBodyAdvice添加进requestResponseBodyAdviceBeans里
if (RequestBodyAdvice.class.isAssignableFrom(beanType) || ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
requestResponseBodyAdviceBeans.add(adviceBean);
}
}
//设置requestResponseBodyAdviceBeans到requestResponseBodyAdvice属性
if (!requestResponseBodyAdviceBeans.isEmpty()) {
this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
}
if (logger.isDebugEnabled()) {
int modelSize = this.modelAttributeAdviceCache.size();
int binderSize = this.initBinderAdviceCache.size();
int reqCount = getBodyAdviceCount(RequestBodyAdvice.class);
int resCount = getBodyAdviceCount(ResponseBodyAdvice.class);
if (modelSize == 0 && binderSize == 0 && reqCount == 0 && resCount == 0) {
logger.debug("ControllerAdvice beans: none");
} else {
logger.debug("ControllerAdvice beans: " + modelSize + " @ModelAttribute, " + binderSize +
" @InitBinder, " + reqCount + " RequestBodyAdvice, " + resCount + " ResponseBodyAdvice");
}
}
}
getDefaultArgumentResolvers方法获取默认的参数解析器
/**
* 返回要使用的参数解析器列表,包括内置解析器
* 和通过 {@link #setCustomArgumentResolvers} 提供的自定义解析器。
*/
private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
// 基于注释的参数解析
//解析加了RequestParam注解的参数
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
//解析加了RequestParamMap注解的参数
resolvers.add(new RequestParamMapMethodArgumentResolver());
//解析加了PathVariable注解的参数
resolvers.add(new PathVariableMethodArgumentResolver());
//解析加了PathVariable注解的map
resolvers.add(new PathVariableMapMethodArgumentResolver());
//解析加了MatrixVariable注解的参数
resolvers.add(new MatrixVariableMethodArgumentResolver());
//解析加了MatrixVariable注解的map参数
resolvers.add(new MatrixVariableMapMethodArgumentResolver());
//
resolvers.add(new ServletModelAttributeMethodProcessor(false));
//解析加了RequestBody或加了ResponseBody注解的参数或方法
resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
//解析RequestPart注解的参数
resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
//解析加了RequestHeader注解的参数
resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
//解析加了RequestHeader注解的map参数
resolvers.add(new RequestHeaderMapMethodArgumentResolver());
//解析HttpServletRequest的cookie值
resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
//解析加了Value注解的参数
resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
//解析加了SessionAttribute的参数
resolvers.add(new SessionAttributeMethodArgumentResolver());
//解析加了RequestAttribute的参数
resolvers.add(new RequestAttributeMethodArgumentResolver());
// 基于类型的参数解析
//解析 servlet 支持的与请求相关的方法参数
resolvers.add(new ServletRequestMethodArgumentResolver());
//解析 servlet 支持的响应相关方法参数
resolvers.add(new ServletResponseMethodArgumentResolver());
//解析 {@link HttpEntity} 和 {@link RequestEntity} 方法参数值
//并且还处理 {@link HttpEntity} 和 {@link ResponseEntity} 返回值。
resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
//解析加了RedirectAttributes注解的参数
resolvers.add(new RedirectAttributesMethodArgumentResolver());
//解析model参数,并处理Model返回值
resolvers.add(new ModelMethodProcessor());
//解析map参数并处理map返回值
resolvers.add(new MapMethodProcessor());
//解析错误返回信息,BindingResult
resolvers.add(new ErrorsMethodArgumentResolver());
//解析SessionStatus参数
resolvers.add(new SessionStatusMethodArgumentResolver());
//解析UriComponentsBuilder类型的参数
resolvers.add(new UriComponentsBuilderMethodArgumentResolver());
// 自定义参数解析
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}
//包罗万象
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
resolvers.add(new ServletModelAttributeMethodProcessor(true));
return resolvers;
}
getDefaultInitBinderArgumentResolvers方法用于加载InitBinder的参数解析器
/**
* 返回用于 {@code @InitBinder} 的参数解析器列表
* 包括内置和自定义解析器的方法。
*/
private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() {
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
// 基于注释的参数解析
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
resolvers.add(new RequestParamMapMethodArgumentResolver());
resolvers.add(new PathVariableMethodArgumentResolver());
resolvers.add(new PathVariableMapMethodArgumentResolver());
resolvers.add(new MatrixVariableMethodArgumentResolver());
resolvers.add(new MatrixVariableMapMethodArgumentResolver());
resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
resolvers.add(new SessionAttributeMethodArgumentResolver());
resolvers.add(new RequestAttributeMethodArgumentResolver());
// 基于类型的参数解析
resolvers.add(new ServletRequestMethodArgumentResolver());
resolvers.add(new ServletResponseMethodArgumentResolver());
//自定义参数
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}
// 包罗万象
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
return resolvers;
}
getDefaultReturnValueHandlers方法加载默认的返回值处理器
/**
* 返回要使用的返回值处理程序列表,包括内置和
* 通过 {@link #setReturnValueHandlers} 提供的自定义处理程序。
*/
private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>();
// 单一用途的返回值类型
//加载返回值类型是ModelAndView的处理器
handlers.add(new ModelAndViewMethodReturnValueHandler());
//加载model类型的返回值的处理器
handlers.add(new ModelMethodProcessor());
//加载返回值类型是View的处理器
handlers.add(new ViewMethodReturnValueHandler());
//加载ResponseBodyEmitter返回值类型的处理器
handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),
this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));
//加载StreamingResponseBody类型的处理器
handlers.add(new StreamingResponseBodyReturnValueHandler());
//加载处理HttpEntity和ResponseEntity返回值的处理器
handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
//加载HttpHeaders返回值的处理器
handlers.add(new HttpHeadersReturnValueHandler());
//加载Callable类型返回值的处理器
handlers.add(new CallableMethodReturnValueHandler());
//加载DeferredResult类型返回值的处理器
handlers.add(new DeferredResultMethodReturnValueHandler());
//处理WebAsyncTask返回值类型的处理器
handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));
// 基于注解的返回值类型
//解析加了ModelAttribute注解的处理器
handlers.add(new ModelAttributeMethodProcessor(false));
//解析加了ResponseBody的处理器
handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
// 多用途返回值类型
//加载处理类型是void或String处理器
handlers.add(new ViewNameMethodReturnValueHandler());
//加载返回值是map的处理器
handlers.add(new MapMethodProcessor());
// 自定义返回值类型
if (getCustomReturnValueHandlers() != null) {
handlers.addAll(getCustomReturnValueHandlers());
}
//包罗万象
if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {
handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));
} else {
handlers.add(new ModelAttributeMethodProcessor(true));
}
return handlers;
}
5.请求处理流程分析
覆盖了父类的supportsInternal抽象方法,支持处理HandlerMethod
/**
* 始终返回 {@code true},因为任何方法参数和返回值
* 类型会以某种方式进行处理。无法识别方法参数
* 被任何 HandlerMethodArgumentResolver 解释为请求参数
* 如果它是简单类型,否则作为模型属性。一个返回值
* 不被任何 HandlerMethodReturnValueHandler 识别的将被解释
* 作为模型属性。
*/
@Override
protected boolean supportsInternal(HandlerMethod handlerMethod) {
return true;
}
重新了父类的handleInternal抽象方法处理请求
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
//检查是否支持此请求方法
checkRequest(request);
// 如果需要,在同步块中执行 invokeHandlerMethod。
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
} else {
//没有可用的 HttpSession -> 不需要互斥量
mav = invokeHandlerMethod(request, response, handlerMethod);
}
} else {
//根本不需要会话同步...
mav = invokeHandlerMethod(request, response, handlerMethod);
}
//返回值中有Cache-Control的header参数
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
//session属性处理器处理
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
} else {
prepareResponse(response);
}
}
return mav;
}
主要方法invokeHandlerMethod,调用加了RequestMapping注解的方法,执行对应的请求逻辑,返回ModelAndView
/**
* 调用 {@link RequestMapping} 处理程序方法准备 {@link ModelAndView}
* 如果需要视图分辨率。
*
* @see #createInvocableHandlerMethod(HandlerMethod)
* @since 4.2
*/
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
//创建ServletWebRequest
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
//获取默认的处理WebDataBinder的工厂
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
//获取处理model的工厂
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);
}
//设置处理WebDataBinder的工厂
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();
LogFormatUtils.traceDebug(logger, traceOn -> {
String formatted = LogFormatUtils.formatValue(result, !traceOn);
return "Resume with async result [" + formatted + "]";
});
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
//执行请求方法处理
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
//获取ModelAndView
return getModelAndView(mavContainer, modelFactory, webRequest);
} finally {
webRequest.requestCompleted();
}
}
invokeAndHandle方法,执行处理方法并处理返回值
/**
* 在给定请求的上下文中解析其参数值后调用该方法。
* <p>参数值通常通过
* {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolver}。
* {@code providedArgs}参数可以提供直接使用的参数值,
* 也就是说,没有辩论决议。提供的参数值示例包括
* {@link WebDataBinder}、{@link SessionStatus}或引发的异常实例。
* 在参数解析程序之前检查提供的参数值。
* <p>委托给{@link#getMethodArgumentValues}并使用
*
* 已解决的争论。
* @param request the current request
* @param mavContainer the ModelAndViewContainer for this request
* @param providedArgs "given" arguments matched by type, not resolved
* @return the raw value returned by the invoked method
* @throws Exception raised if no suitable argument resolver can be found,
* or if the method raised an exception
* @see #getMethodArgumentValues
* @see #doInvoke
*/
@Nullable
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);
}
getMethodArgumentValues方法处理参数解析
/**
* 获取当前请求的方法参数值,检查提供的
* 参数值,并返回到配置的参数解析程序。
* <p>生成的数组将被传递到{@link#doInvoke}。
* @since 5.1.2
*/
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);
args[i] = findProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
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) {
// Leave stack trace for later, exception may actually be resolved and handled...
if (logger.isDebugEnabled()) {
String exMsg = ex.getMessage();
if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {
logger.debug(formatArgumentError(parameter, exMsg));
}
}
throw ex;
}
}
return args;
}
反射处理方法
/**
* 使用给定的参数值调用处理程序方法。
*/
@Nullable
protected Object doInvoke(Object... args) throws Exception {
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
return getBridgedMethod().invoke(getBean(), args);
}
catch (IllegalArgumentException ex) {
assertTargetBean(getBridgedMethod(), getBean(), args);
String text = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument");
throw new IllegalStateException(formatInvokeError(text, args), ex);
}
catch (InvocationTargetException ex) {
// Unwrap for HandlerExceptionResolvers ...
Throwable targetException = ex.getTargetException();
if (targetException instanceof RuntimeException) {
throw (RuntimeException) targetException;
}
else if (targetException instanceof Error) {
throw (Error) targetException;
}
else if (targetException instanceof Exception) {
throw (Exception) targetException;
}
else {
throw new IllegalStateException(formatInvokeError("Invocation failure", args), targetException);
}
}
}