org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
--------------RequestMappingHandlerMapping如何感知Interceptors-------------------
// 1.通过xml声明注入的拦截器
org.springframework.web.servlet.handler.AbstractHandlerMapping.setInterceptors(Object... interceptors)
{
this.interceptors.addAll(Arrays.asList(interceptors));
}
// 2.自动扫描拦截器
org.springframework.context.support.ApplicationObjectSupport.setApplicationContext(ApplicationContext context)
{
this.applicationContext = context; // === org.springframework.web.context.support.XmlWebApplicationContext
initApplicationContext(context);
{
org.springframework.web.context.support.WebApplicationObjectSupport.initApplicationContext(ApplicationContext context)
{
org.springframework.context.support.ApplicationObjectSupport.initApplicationContext(ApplicationContext context)
{
org.springframework.web.servlet.handler.AbstractHandlerMapping.initApplicationContext()
{
AbstractHandlerMapping.extendInterceptors(this.interceptors); // 空方法
AbstractHandlerMapping.detectMappedInterceptors(this.adaptedInterceptors); // 扫描applicationContext.xml文件,找出MappedInterceptor类型的bean
{
mappedInterceptors.addAll(
BeanFactoryUtils.beansOfTypeIncludingAncestors(
getApplicationContext(), MappedInterceptor.class, true, false).values());
}
AbstractHandlerMapping.initInterceptors(); // 适配 Interceptors
{
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){ // 适配拦截器 ,注册Interceptor ----- 1
if (interceptor instanceof HandlerInterceptor) {
return (HandlerInterceptor) interceptor;
}
else if (interceptor instanceof WebRequestInterceptor) {
return new WebRequestHandlerInterceptorAdapter((WebRequestInterceptor) interceptor);
}
else {
throw new IllegalArgumentException("Interceptor type not supported: " + interceptor.getClass().getName());
}
});
}
}
}
}
}
this.servletContext = ((WebApplicationContext) context).getServletContext();
if (this.servletContext != null) {
initServletContext(this.servletContext); // 空方法
}
}
}
}
--------------RequestMappingHandlerMapping如何扫描Handler-------------------
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet()
{
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods()
{
String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
getApplicationContext().getBeanNamesForType(Object.class)); // 扫描所有bean
for (String beanName : beanNames) {
if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) { // 不处理被代理的bean
Class<?> beanType = null;
try {
beanType = getApplicationContext().getType(beanName);
}
catch (Throwable ex) {
}
if (beanType != null && isHandler(beanType){ // 含有@Controller注解或者@RequestMapping注解
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) || AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}) {
AbstractHandlerMethodMapping.detectHandlerMethods(beanName); // !!!!
{
Class<?> handlerType = (handler instanceof String ? getApplicationContext().getType((String) handler) : handler.getClass()); // 获取bean的类型
final Class<?> userType = ClassUtils.getUserClass(handlerType);
Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
new MethodIntrospector.MetadataLookup<T>() {
@Override
public T inspect(Method method) {
try {
return RequestMappingHandlerMapping.getMappingForMethod(method, userType); // 识别@RequestMapping注解,获取配置
{
RequestMappingInfo info = RequestMappingHandlerMapping.createRequestMappingInfo(method); // 获取方法的@RequestMapping注解
{
RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
RequestCondition<?> condition = (element instanceof Class ?
getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));
return (requestMapping != null ? RequestMappingHandlerMapping.createRequestMappingInfo(requestMapping, condition) : null);
{
return RequestMappingInfo
.paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
.methods(requestMapping.method())
.params(requestMapping.params())
.headers(requestMapping.headers())
.consumes(requestMapping.consumes())
.produces(requestMapping.produces())
.mappingName(requestMapping.name())
.customCondition(customCondition)
.options(RequestMappingHandlerMapping.this.config)
.build();
}
}
if (info != null) {
RequestMappingInfo typeInfo = RequestMappingHandlerMapping.createRequestMappingInfo(handlerType);// 获取类的@RequestMapping注解
{
RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
RequestCondition<?> condition = (element instanceof Class ?
getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));
return (requestMapping != null ? RequestMappingHandlerMapping.createRequestMappingInfo(requestMapping, condition) : null);
{
return RequestMappingInfo
.paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
.methods(requestMapping.method())
.params(requestMapping.params())
.headers(requestMapping.headers())
.consumes(requestMapping.consumes())
.produces(requestMapping.produces())
.mappingName(requestMapping.name())
.customCondition(customCondition)
.options(this.config)
.build();
}
}
if (typeInfo != null) {
info = typeInfo.combine(info); // 合并方法上和类上的 @RequestMapping注解信息
}
}
return info;
}
}
catch (Throwable ex) {
}
}
});
for (Map.Entry<Method, T> entry : methods.entrySet()) {
Method invocableMethod = AopUtils.selectInvocableMethod(entry.getKey(), userType); // 获取可调用方法,可能是本身
T mapping = entry.getValue();
// handler === "beanName0"
// mapping === org.springframework.web.servlet.mvc.method.RequestMappingInfo
registerHandlerMethod(handler, invocableMethod, mapping); // !!!!
{
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry.register(T mapping, Object handler, Method method)
{
// handler === "beanName0"
// mapping === org.springframework.web.servlet.mvc.method.RequestMappingInfo -- @RequestMapping注解信息
HandlerMethod handlerMethod = AbstractHandlerMethodMapping.createHandlerMethod(handler, method); // 方法信息
{
HandlerMethod handlerMethod;
if (handler instanceof String) {
String beanName = (String) handler;
// getApplicationContext() === org.springframework.web.context.support.XmlWebApplicationContext
// getApplicationContext().getAutowireCapableBeanFactory() === org.springframework.beans.factory.support.DefaultListableBeanFactory
handlerMethod = new HandlerMethod(beanName,getApplicationContext().getAutowireCapableBeanFactory(), method); // !!!
}
else {
handlerMethod = new HandlerMethod(handler, method); // 使用HandlerMethod对象来描述调用者信息 ----- !!!
}
return handlerMethod;
}
this.mappingLookup.put(mapping, handlerMethod); // 注册HandlerMethod ----- 2
List<String> directUrls = getDirectUrls(mapping); // 获取 @RequestMapping注解上配置的path,要求path不是带*或者?
for (String url : directUrls) {
this.urlLookup.add(url, mapping); // !!! 注册
}
String name = null;
if (getNamingStrategy() != null) {
// !!! org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMethodMappingNamingStrategy,生成规则是:"类名中的每个大写字符"+"#"+"方法名"
name = getNamingStrategy().getName(handlerMethod, mapping);
addMappingName(name, handlerMethod);
{
List<HandlerMethod> oldList = this.nameLookup.get(name);
if (oldList == null) {
oldList = Collections.<HandlerMethod>emptyList();
}
for (HandlerMethod current : oldList) {
if (handlerMethod.equals(current)) {
return;
}
}
List<HandlerMethod> newList = new ArrayList<HandlerMethod>(oldList.size() + 1);
newList.addAll(oldList);
newList.add(handlerMethod);
this.nameLookup.put(name, newList); // !!! 注册
}
}
CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping); // 跨域配置
if (corsConfig != null) {
this.corsLookup.put(handlerMethod, corsConfig);
}
this.registry.put(mapping, new MappingRegistration<T>(mapping, handlerMethod, directUrls, name)); // !!! 注册
}
}
}
}
}
}
}
}
}
-------------------- RequestMappingHandlerMapping 如何匹配符合条件的Handler--------------------------
org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(HttpServletRequest request)
{
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(HttpServletRequest request)
{
1、String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); // 请求资源的地址
2、HandlerMethod handlerMethod = AbstractHandlerMethodMapping.lookupHandlerMethod(lookupPath, request);
{
List<Match> matches = new ArrayList<Match>();
// this.mappingRegistry === org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry
List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath); // 完整匹配
{
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry.getMappingsByUrl(String urlPath)
{
return this.urlLookup.get(urlPath);
}
}
if (directPathMatches != null) {
addMatchingMappings(directPathMatches, matches, request);
}
if (matches.isEmpty()) {
// No choice but to go through all mappings...
// this.mappingRegistry.getMappings() === mappingLookup
addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request); // !!! 迭代进行匹配
{
for (T mapping : mappings) {
T match = getMatchingMapping(mapping, request);
{
org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getMatchingMapping(RequestMappingInfo info, HttpServletRequest request)
{
// info === org.springframework.web.servlet.mvc.method.RequestMappingInfo
return info.getMatchingCondition(request);
}
}
if (match != null) {
matches.add(new Match(match, this.mappingRegistry.getMappings().get(mapping)));
}
}
}
}
Match bestMatch = matches.get(0);
if (matches.size() > 1) { // 多个规则命中请求地址
if (CorsUtils.isPreFlightRequest(request)) {
return PREFLIGHT_AMBIGUOUS_MATCH;
}
Match secondBestMatch = matches.get(1);
if (comparator.compare(bestMatch, secondBestMatch) == 0) {
Method m1 = bestMatch.handlerMethod.getMethod();
Method m2 = secondBestMatch.handlerMethod.getMethod();
throw new IllegalStateException("Ambiguous handler methods mapped for HTTP path '" +
request.getRequestURL() + "': {" + m1 + ", " + m2 + "}");
}
}
org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleMatch(bestMatch.mapping, lookupPath, request);
{
super.handleMatch(info, lookupPath, request);
{
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, lookupPath); // -- 匹配的信息放入request
}
String bestPattern;
Map<String, String> uriVariables;
Map<String, String> decodedUriVariables;
Set<String> patterns = info.getPatternsCondition().getPatterns();
if (patterns.isEmpty()) {
bestPattern = lookupPath;
uriVariables = Collections.emptyMap();
decodedUriVariables = Collections.emptyMap();
}
else {
bestPattern = patterns.iterator().next();
// getPathMatcher() === org.springframework.util.AntPathMatcher
uriVariables = getPathMatcher().extractUriTemplateVariables(bestPattern, lookupPath); // 模板变量
decodedUriVariables = getUrlPathHelper().decodePathVariables(request, uriVariables); // 解码后的变量
}
request.setAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE, bestPattern); // -- 匹配的信息放入request
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, decodedUriVariables); // -- 匹配的信息放入request
if (isMatrixVariableContentAvailable()) { // 多维数组
Map<String, MultiValueMap<String, String>> matrixVars = extractMatrixVariables(request, uriVariables);
request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, matrixVars);
}
if (!info.getProducesCondition().getProducibleMediaTypes().isEmpty()) {
Set<MediaType> mediaTypes = info.getProducesCondition().getProducibleMediaTypes();
request.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, mediaTypes);
}
}
return bestMatch.handlerMethod;
}
3、return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
if (handler == null) {
handler = getDefaultHandler(); // 使用默认的
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}
HandlerExecutionChain executionChain = AbstractHandlerMapping.getHandlerExecutionChain(handler, request); // !!!!
{
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
for (HandlerInterceptor interceptor : this.adaptedInterceptors) { // 匹配符合条件的Interceptor
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { // 匹配本拦截器
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
else {
chain.addInterceptor(interceptor); // 添加拦截器
}
}
return chain;
}
if (CorsUtils.isCorsRequest(request)) { // 是跨域请求
CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
--------------------执行Handler的过程--------------------------
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.afterPropertiesSet()
{
// Do this first, it may add ResponseBody advice beans
initControllerAdviceCache();
{
List<ControllerAdviceBean> beans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext()); // 带有 @ControllerAdvice注解的类
AnnotationAwareOrderComparator.sort(beans);
List<Object> requestResponseBodyAdviceBeans = new ArrayList<Object>();
for (ControllerAdviceBean bean : beans) {
Set<Method> attrMethods = MethodIntrospector.selectMethods(bean.getBeanType(), MODEL_ATTRIBUTE_METHODS); //带有 @ModelAttribute注解的方法
if (!attrMethods.isEmpty()) {
this.modelAttributeAdviceCache.put(bean, attrMethods);
}
Set<Method> binderMethods = MethodIntrospector.selectMethods(bean.getBeanType(), INIT_BINDER_METHODS);// 带有@InitBinder注解的方法
if (!binderMethods.isEmpty()) {
this.initBinderAdviceCache.put(bean, binderMethods);
}
if (RequestBodyAdvice.class.isAssignableFrom(bean.getBeanType())) { // bean 实现了 RequestBodyAdvice 接口
requestResponseBodyAdviceBeans.add(bean);
}
if (ResponseBodyAdvice.class.isAssignableFrom(bean.getBeanType())) { // bean 实现了 ResponseBodyAdvice 接口
requestResponseBodyAdviceBeans.add(bean);
}
}
if (!requestResponseBodyAdviceBeans.isEmpty()) {
this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
}
}
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);
}
}
// ---------------解析Handler、执行Handler的拦截器、执行Handler方法、渲染视图----------------------------
try {
org.springframework.web.servlet.DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response)
{
// 如果不是文件上传,processedRequest就是request本身
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest); // 决策一个适合processedRequest的Handler,执行链管理器HandlerExecutionChain
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// ha === org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 决策一个适合Handler的“Handler适配器”, 四种类型的适配器
// 执行拦截器的前置方法
org.springframework.web.servlet.HandlerExecutionChain.applyPreHandle(processedRequest, response)
{
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)) { // 如果interceptor执行的返回值是false
triggerAfterCompletion(request, response, null); // 如果没有过,直接触发结束的
{
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = this.interceptorIndex; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
try {
interceptor.afterCompletion(request, response, this.handler, ex);
}
catch (Throwable ex2) {
logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
}
}
}
}
return false;
}
this.interceptorIndex = i;
}
}
return true;
}
// 执行业务方法
mv = org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handle(processedRequest, response, mappedHandler.getHandler()); // 执行handler的方法,返回值
{
return org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(HttpServletRequest request, HttpServletResponse response, Object handler)
{
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod)
{
ModelAndView mav;
checkRequest(request); // 检查提交的方式和Session是否提供
mav = invokeHandlerMethod(request, response, handlerMethod); // !!!! mav === org.springframework.web.servlet.ModelAndView
{
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod)
{
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
WebDataBinderFactory binderFactory = RequestMappingHandlerAdapter.getDataBinderFactory(handlerMethod); // !!! 归类带@InitBinder注解的方法
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory); // !!! 归类带@ModelAttribute注解的方法
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers); // 参数解析器
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers); // 返回值处理器
invocableMethod.setDataBinderFactory(binderFactory); // 初始化处理器
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer); // 参数名识别器
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
// modelFactory === org.springframework.web.method.annotation.ModelFactory
modelFactory.initModel(webRequest, mavContainer, invocableMethod); // 迭代调用带@ModelAttribute注解的方法,返回值会以“返回值类型短名”作为键,放入mavContainer ------> 调用含 @ModelAttribute 注解的方法
{
// sessionAttributesHandler ==== org.springframework.web.method.annotation.SessionAttributesHandler
// handlerMethod === org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod
Map<String, ?> sessionAttributes = this.sessionAttributesHandler.retrieveAttributes(request); // 从session中获取值
container.mergeAttributes(sessionAttributes); // 合并值
invokeModelAttributeMethods(request, container); // 迭代调用带@ModelAttribute注解的方法
{
org.springframework.web.method.annotation.ModelFactory.invokeModelAttributeMethods(NativeWebRequest request, ModelAndViewContainer container)
{
while (!this.modelMethods.isEmpty()) { // 迭代调用
// getNextModelMethod(container) === org.springframework.web.method.annotation.ModelFactory.ModelMethod
InvocableHandlerMethod modelMethod = getNextModelMethod(container).getHandlerMethod(); // 获取下一个带@ModelAttribute注解的方法
// modelMethod === org.springframework.web.method.support.InvocableHandlerMethod
ModelAttribute ann = modelMethod.getMethodAnnotation(ModelAttribute.class); // 获取方法上的@ModelAttribute注解
if (container.containsAttribute(ann.name())) {
if (!ann.binding()) {
container.setBindingDisabled(ann.name());
}
continue;
}
Object returnValue = modelMethod.invokeForRequest(request, container); // !!!!调用带@ModelAttribute注解的方法
{
// providedArgs === null
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); // 参数值
{
MethodParameter[] parameters = getMethodParameters(); // 目标方法的参数
Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
MethodParameter parameter = parameters[i];
// parameterNameDiscoverer === org.springframework.core.DefaultParameterNameDiscoverer
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
args[i] = resolveProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
// argumentResolvers === org.springframework.web.method.support.HandlerMethodArgumentResolverComposite
if (this.argumentResolvers.supportsParameter(parameter)) { // 支持此种类型的参数
try {
args[i] = this.argumentResolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory); // 获取指定类型的参数的值
{
// ....
}
continue;
}
}
}
return args;
}
Object returnValue = doInvoke(args); // 传递参数,调用方法 ---- 调用“带@ModelAttribute注解的方法” ---- 1
{
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
return getBridgedMethod().invoke(getBean(), args); // 调用方法
}
}
return returnValue;
}
if (!modelMethod.isVoid()){ // 返回值不是void
String returnValueName = getNameForReturnValue(returnValue, modelMethod.getReturnType()); // 返回值的类型的“短名”作为键名
if (!ann.binding()) {
container.setBindingDisabled(returnValueName);
}
if (!container.containsAttribute(returnValueName)) {
container.addAttribute(returnValueName, returnValue); // 把返回值放入container,返回值的类型的“短名”作为键名
}
}
}
}
}
for (String name : findSessionAttributeArguments(handlerMethod)) {
if (!container.containsAttribute(name)) {
Object value = this.sessionAttributesHandler.retrieveAttribute(request, name); // 从session中获取值
if (value == null) {
throw new HttpSessionRequiredException("Expected session attribute '" + name + "'", name);
}
container.addAttribute(name, value);
}
}
}
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 === org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod
invocableMethod.invokeAndHandle(webRequest, mavContainer); // !!!调用业务方法,让“返回值处理器”处理后,把值放入mavContainer
{
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs); // 调用方法
{
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs)
{
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); // 参数值
{
MethodParameter[] parameters = getMethodParameters(); // 目标方法的参数
Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
MethodParameter parameter = parameters[i];
// parameterNameDiscoverer === org.springframework.core.DefaultParameterNameDiscoverer
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
args[i] = resolveProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
// argumentResolvers === org.springframework.web.method.support.HandlerMethodArgumentResolverComposite
if (this.argumentResolvers.supportsParameter(parameter)) { // 支持此种类型的参数
try {
// 获取指定类型的参数的值 ---- 可能调用“带@InitBinder注解的方法”
args[i] = this.argumentResolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
{
// 情况1,不调用“带@InitBinder注解的方法”, 如: resolver === org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver
{
HandlerMethodArgumentResolver resolver = HandlerMethodArgumentResolverComposite.getArgumentResolver(parameter); // 获取参数解析器
return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory); // 获取参数值
}
// 情况2,调用“带@InitBinder注解的方法”, 如: resolver === org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor
{
org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory)
{
// webRequest === org.springframework.web.context.request.ServletWebRequest
String name = ModelFactory.getNameForParameter(parameter); // 变量名
Object attribute = (mavContainer.containsAttribute(name) ? mavContainer.getModel().get(name) :
createAttribute(name, parameter, binderFactory, webRequest)); // 创建参数类型的对象 cn.java.demo.webmvc.form.UserLoginForm
{
return BeanUtils.instantiateClass(methodParam.getParameterType());
}
if (!mavContainer.isBindingDisabled(name)) {
ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
if (ann != null && !ann.binding()) {
mavContainer.setBindingDisabled(name);
}
}
// binderFactory == org.springframework.web.servlet.mvc.method.annotation.ServletRequestDataBinderFactory
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name); //
{
org.springframework.web.bind.support.DefaultDataBinderFactory.createBinder(NativeWebRequest webRequest, Object target, String objectName)
{
// target === cn.java.demo.webmvc.form.UserLoginForm
WebDataBinder dataBinder = DefaultDataBinderFactory.createBinderInstance(target, objectName, webRequest);
{
return new WebRequestDataBinder(target, objectName);
{
target === cn.java.demo.webmvc.form.UserLoginForm
objectName === userLoginForm
}
}
if (this.initializer != null) {
this.initializer.initBinder(dataBinder, webRequest); // ------> 初始化 binder
}
InitBinderDataBinderFactory.initBinder(dataBinder, webRequest);//!!!!
{
org.springframework.web.method.annotation.InitBinderDataBinderFactory.initBinder(WebDataBinder binder, NativeWebRequest request)
{
for (InvocableHandlerMethod binderMethod : this.binderMethods) { // ---- 迭代调用“带@InitBinder注解的方法” ---- 2
if (isBinderMethodApplicable(binderMethod, binder){
InitBinder annot = initBinderMethod.getMethodAnnotation(InitBinder.class); // 有@InitBinder注解
Collection<String> names = Arrays.asList(annot.value());
return (names.size() == 0 || names.contains(binder.getObjectName())); // 1、注解上没有配置值; 2、@InitBinder注解上有配置值,并且在值域里面
}) { // !!!!
// org.springframework.web.method.support.InvocableHandlerMethod
Object returnValue = binderMethod.invokeForRequest(request, null, binder); // !!!
{
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); // 参数值
{
MethodParameter[] parameters = getMethodParameters(); // 目标方法的参数
Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
MethodParameter parameter = parameters[i];
// parameterNameDiscoverer === org.springframework.core.DefaultParameterNameDiscoverer
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
args[i] = resolveProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
// argumentResolvers === org.springframework.web.method.support.HandlerMethodArgumentResolverComposite
if (this.argumentResolvers.supportsParameter(parameter)) { // 支持此种类型的参数
try {
// 1、解析请求数据成对象
// 2、创建binder、初始化binder、迭代调用“带@InitBinder注解的方法”
// 3、调用binder获取值,设置到 ModelAndViewContainer
args[i] = this.argumentResolvers.resolveArgument(
parameter, mavContainer, request, this.dataBinderFactory); // 获取指定类型的参数的值
continue;
}
catch (Exception ex) {
throw ex;
}
}
if (args[i] == null) {
throw new IllegalStateException("Could not resolve method parameter at index " +
parameter.getParameterIndex() + " in " + parameter.getMethod().toGenericString() +
": " + getArgumentResolutionErrorMessage("No suitable resolver for", i));
}
}
return args;
}
Object returnValue = doInvoke(args); // 传递参数,调用方法
{
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
return getBridgedMethod().invoke(getBean(), args); // 调用方法
}
}
return returnValue;
}
if (returnValue != null) { // 不能有返回值
throw new IllegalStateException("@InitBinder methods should return void: " + binderMethod);
}
}
}
}
}
return dataBinder;
}
}
if (binder.getTarget() != null) {
if (!mavContainer.isBindingDisabled(name)) {
ModelAttributeMethodProcessor.bindRequestParameters(binder, webRequest); // 把webRequest.getNativeRequest(ServletRequest.class)的值设置到target
{
((WebRequestDataBinder) binder).bind(request);
{
org.springframework.web.bind.support.WebRequestDataBinder.bind(WebRequest request)
{
MutablePropertyValues mpvs = new MutablePropertyValues(request.getParameterMap()); // request中的参数
if (isMultipartRequest(request) && request instanceof NativeWebRequest) {
MultipartRequest multipartRequest = ((NativeWebRequest) request).getNativeRequest(MultipartRequest.class);
if (multipartRequest != null) {
bindMultipart(multipartRequest.getMultiFileMap(), mpvs);
}
else if (servlet3Parts) {
HttpServletRequest serlvetRequest = ((NativeWebRequest) request).getNativeRequest(HttpServletRequest.class);
new Servlet3MultipartHelper(isBindEmptyMultipartFiles()).bindParts(serlvetRequest, mpvs);
}
}
WebRequestDataBinder.doBind(mpvs);
{
org.springframework.web.bind.WebDataBinder.doBind(MutablePropertyValues mpvs)
{
WebDataBinder.checkFieldDefaults(mpvs);
WebDataBinder.checkFieldMarkers(mpvs);
super.doBind(mpvs);
{
org.springframework.validation.DataBinder.doBind(MutablePropertyValues mpvs)
{
DataBinder.checkAllowedFields(mpvs);
DataBinder.checkRequiredFields(mpvs);
DataBinder.applyPropertyValues(mpvs); // 把mpvs的属性值设置到beanWrapper
{
// Bind request parameters onto target object.
getPropertyAccessor(){
BeanPropertyBindingResult result = new BeanPropertyBindingResult(getTarget(), // getTarget() ==== cn.java.demo.webmvc.form.UserLoginForm 对象
getObjectName(), isAutoGrowNestedPaths(), getAutoGrowCollectionLimit());
return result.getPropertyAccessor();
}.setPropertyValues(mpvs, isIgnoreUnknownFields(), isIgnoreInvalidFields()); // 把mpvs的属性值设置到beanWrapper
}
}
}
}
}
}
}
}
}
validateIfApplicable(binder, parameter); // 校验 -------------- 校验
{
Annotation[] annotations = methodParam.getParameterAnnotations();
for (Annotation ann : annotations) {
Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class); // 注解类上的注解
if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));
Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});
// binder === org.springframework.web.bind.support.WebRequestDataBinder
binder.validate(validationHints);
{
org.springframework.validation.DataBinder.validate(Object... validationHints)
{
for (Validator validator : getValidators()) {
if (!ObjectUtils.isEmpty(validationHints) && validator instanceof SmartValidator) {
((SmartValidator) validator).validate(getTarget(), getBindingResult(), validationHints); // 迭代调用在“有@InitBinder注解”方法中注入的校验器
}
else if (validator != null) {
validator.validate(getTarget(), getBindingResult());
}
}
}
}
break;
}
}
}
if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter){
int i = methodParam.getParameterIndex();
Class<?>[] paramTypes = methodParam.getMethod().getParameterTypes(); // 参数列表
boolean hasBindingResult = (paramTypes.length > (i + 1) && Errors.class.isAssignableFrom(paramTypes[i + 1])); // 绑定对象的“后一个”参数是“存放绑定结果”的对象
return !hasBindingResult;
}) { // 如果校验不通过
throw new BindException(binder.getBindingResult());
}
}
// Add resolved attribute and BindingResult at the end of the model
// binder === org.springframework.web.bind.support.WebRequestDataBinder
// binder.getBindingResult() === org.springframework.validation.BeanPropertyBindingResult
Map<String, Object> bindingResultModel = binder.getBindingResult().getModel(); // model.put(attribute,webRequest); // model.put("org.springframework.validation.BindingResult.attribute",org.springframework.validation.BeanPropertyBindingResult对象)
mavContainer.removeAttributes(bindingResultModel);
mavContainer.addAllAttributes(bindingResultModel); // 绑定结果放入mavContainer
return binder.convertIfNecessary(binder.getTarget(), parameter.getParameterType(), parameter); // 返回值是binder.getTarget()
}
}
}
continue;
}
}
}
return args;
}
Object returnValue = doInvoke(args); // 传递参数,调用方法 --- 调用“业务方法”
{
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
return getBridgedMethod().invoke(getBean(), args); // 调用方法
}
}
return returnValue;
}
}
setResponseStatus(webRequest); // 发送响应状态
if (returnValue == null) { // 没有返回值
if (isRequestNotModified(webRequest) || hasResponseStatus() || mavContainer.isRequestHandled()) {
mavContainer.setRequestHandled(true);
return;
}
}
else if (StringUtils.hasText(this.responseReason)) {
mavContainer.setRequestHandled(true);
return;
}
mavContainer.setRequestHandled(false);
try {
// returnValueHandlers === org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest); // 处理返回值,处理返回值
{
// “结果处理器”会把“返回值”设置到“mavContainer对象”
}
}
}
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
return RequestMappingHandlerAdapter.getModelAndView(mavContainer, modelFactory, webRequest); // 处理返回的 org.springframework.web.servlet.ModelAndView
{
modelFactory.updateModel(webRequest, mavContainer);
if (mavContainer.isRequestHandled()) {
return null;
}
ModelMap model = mavContainer.getModel(); // 数据
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus()); // 创建一个新的ModelAndView对象
if (!mavContainer.isViewReference()) {
mav.setView((View) mavContainer.getView());
}
if (model instanceof RedirectAttributes) {
Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
}
return mav;
}
}
finally {
webRequest.requestCompleted();
}
}
}
if (!response.containsHeader(HEADER_CACHE_CONTROL)) { // 缓存控制
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { // 有使用@SessionAttributes注解
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); // 发送控制“浏览器缓存”的Header
}
else {
prepareResponse(response); // 发送控制“浏览器缓存”的Header
}
}
return mav;
}
}
}
// 如果没有设置“视图”信息,会自动应用“视图”
DispatcherServlet.applyDefaultViewName(processedRequest, mv);
{
if (mv != null && !mv.hasView()) {
mv.setViewName(getDefaultViewName(request){
// org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
return this.viewNameTranslator.getViewName(request);
}); // 在此可以“篡改模板路径”
}
}
// 执行拦截器的后置方法
org.springframework.web.servlet.HandlerExecutionChain.applyPostHandle(processedRequest, response, mv);
{
HandlerInterceptor[] interceptors = 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);
}
}
}
// 进行渲染
org.springframework.web.servlet.DispatcherServlet.processDispatchResult( request, response, mappedHandler, mv, 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()) {
DispatcherServlet.render(mv, request, response); // 进行渲染 !!!
{
View view;
if (mv.isReference()) {
// We need to resolve the view name.
view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request); // 解析视图
{
for (ViewResolver viewResolver : this.viewResolvers) {
// 如:viewResolver == org.springframework.web.servlet.view.InternalResourceViewResolver
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
}
}
else {
// No need to lookup: the ModelAndView object contains the actual View object.
view = mv.getView();
}
// Delegate to the View object for rendering.
try {
if (mv.getStatus() != null) {
response.setStatus(mv.getStatus().value()); // 响应状态
}
view.render(mv.getModelInternal(), request, response); // 渲染
}
}
}
if (mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, null); // 触发结束方法
{
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = this.interceptorIndex; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
try {
interceptor.afterCompletion(request, response, this.handler, ex);
}
catch (Throwable ex2) {
logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
}
}
}
}
}
}
}
}catch (Exception ex) { // 如果异常还是没有被捕获
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
{
if (mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, ex);
}
throw ex; // 往外抛异常
}
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
...
}
-----------------“参数”的识别--------------------------------
默认“带@ModelAttribute注解或者带@RequestMapping注解的方法”参数解析器:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.getDefaultArgumentResolvers()
{
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();
// Annotation-based argument resolution
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false)); // 参数上有@RequestParam注解,且是普通类型
resolvers.add(new RequestParamMapMethodArgumentResolver()); // 参数上有@RequestParam注解,且是map类型
resolvers.add(new PathVariableMethodArgumentResolver()); // 参数上有@PathVariable注解,且是普通类型
resolvers.add(new PathVariableMapMethodArgumentResolver()); // 参数上有@PathVariable注解,且是map类型
resolvers.add(new MatrixVariableMethodArgumentResolver()); // 参数上有@MatrixVariable注解,且是普通类型
resolvers.add(new MatrixVariableMapMethodArgumentResolver()); // 参数上有@MatrixVariable注解,且是map类型
resolvers.add(new ServletModelAttributeMethodProcessor(false)); // !!! 需要@ModelAttribute注解,尝试获取顺序:1、UriTemplateVariables 2、request.getParameter(attributeName)
resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice)); // !!! 参数上有@RequestBody注解、返回值上有@ResponseBody注解
resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice)); // 参数上有@RequestPart注解、或者MultipartFile类型
resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory())); // 参数上有@RequestHeader注解,且是普通类型
resolvers.add(new RequestHeaderMapMethodArgumentResolver()); // 参数上有@RequestHeader注解,且是map类型
resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory())); // 参数上有@CookieValue注解
resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory())); // 参数上有@Value注解
resolvers.add(new SessionAttributeMethodArgumentResolver()); // 参数上有@SessionAttribute注解
resolvers.add(new RequestAttributeMethodArgumentResolver()); // 参数上有@RequestAttribute注解
// Type-based argument resolution
resolvers.add(new ServletRequestMethodArgumentResolver()); // javax.servlet.ServletRequest等类型的参数
resolvers.add(new ServletResponseMethodArgumentResolver()); // javax.servlet.ServletResponse等类型的参数
resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice)); // 参数类型是 HttpEntity 或者 RequestEntity
resolvers.add(new RedirectAttributesMethodArgumentResolver()); // 参数类型是RedirectAttributes的子类
resolvers.add(new ModelMethodProcessor()); // 参数类型是Model的子类
resolvers.add(new MapMethodProcessor()); // 参数类型是Map的子类
resolvers.add(new ErrorsMethodArgumentResolver()); // 参数类型是Errors的子类,处理“校验结果”参数注入 org.springframework.validation.BindingResult
resolvers.add(new SessionStatusMethodArgumentResolver()); // 参数类型是SessionStatus
resolvers.add(new UriComponentsBuilderMethodArgumentResolver()); // 参数类型是UriComponentsBuilder、ServletUriComponentsBuilder
// Custom arguments
if (getCustomArgumentResolvers() != null) { // 自定义参数值处理器
resolvers.addAll(getCustomArgumentResolvers());
}
// Catch-all
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true)); // 参数上有@RequestParam注解、或MultipartFile类型
resolvers.add(new ServletModelAttributeMethodProcessor(true)); // !!!! 不需要@ModelAttribute注解,尝试获取顺序:1、UriTemplateVariables 2、request.getParameter(attributeName) 3、自定义类型UserLoginForm
return resolvers;
}
默认“带@InitBinder注解的方法”参数解析器:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.getDefaultInitBinderArgumentResolvers()
{
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();
// Annotation-based argument resolution
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());
// Type-based argument resolution
resolvers.add(new ServletRequestMethodArgumentResolver());
resolvers.add(new ServletResponseMethodArgumentResolver());
// Custom arguments
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}
// Catch-all
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
return resolvers;
}
------
使用参数解析器:
org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(...)
----------------“返回值”的处理---------------------
默认“返回值”解析器:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.getDefaultReturnValueHandlers()
{
List<HandlerMethodReturnValueHandler> handlers = new ArrayList<HandlerMethodReturnValueHandler>();
// Single-purpose return value types
handlers.add(new ModelAndViewMethodReturnValueHandler()); // 返回值是ModelAndView类型或者子类
handlers.add(new ModelMethodProcessor()); // 返回值类型是Model类型或者子类
handlers.add(new ViewMethodReturnValueHandler()); // 返回值类型是View类型或者子类
handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters())); // 返回值类型是ResponseEntity类型或者子类
handlers.add(new StreamingResponseBodyReturnValueHandler()); // 返回值类型是StreamingResponseBody类型或者子类
handlers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.contentNegotiationManager, this.requestResponseBodyAdvice)); // 返回值类型是HttpEntity类型或者子类
handlers.add(new HttpHeadersReturnValueHandler()); // 返回值类型是HttpHeaders类型或者子类
handlers.add(new CallableMethodReturnValueHandler()); // 返回值类型是Callable类型或者子类
handlers.add(new DeferredResultMethodReturnValueHandler()); // 返回值类型是DeferredResult、ListenableFuture或者子类
handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory)); // 返回值类型是WebAsyncTask类型或者子类
// Annotation-based return value types
handlers.add(new ModelAttributeMethodProcessor(false)); // 返回值上有@ModelAttribute注解
handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.contentNegotiationManager, this.requestResponseBodyAdvice)); // 返回值上有 @ResponseBody注解
// Multi-purpose return value types
handlers.add(new ViewNameMethodReturnValueHandler()); // 返回void或者字符串
handlers.add(new MapMethodProcessor()); // 返回值类型是Map类型
// Custom return value types
if (getCustomReturnValueHandlers() != null) { // 自定义返回值处理器
handlers.addAll(getCustomReturnValueHandlers());
}
// Catch-all
if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {
handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));
}
else {
handlers.add(new ModelAttributeMethodProcessor(true)); // 返回值上有@ModelAttribute注解
}
return handlers;
}
------
使用“返回值”解析器:
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(...)