这里主要讲解RequestMappingHandlerAdapter
内容主要初始化了:
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
implements BeanFactoryAware, InitializingBean
实现了InitializingBean 接口,则初始化方法为afterPropertiesSet
@Override
public void afterPropertiesSet() {
// Do this first, it may add ResponseBody advice beans
initControllerAdviceCache();
if (this.argumentResolvers == null) {
List resolvers = getDefaultArgumentResolvers();
this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
if (this.initBinderArgumentResolvers == null) {
List resolvers = getDefaultInitBinderArgumentResolvers();
this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
if (this.returnValueHandlers == null) {
List handlers = getDefaultReturnValueHandlers();
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
}
}
private void initControllerAdviceCache() {
if (getApplicationContext() == null) {
return;
}
if (logger.isInfoEnabled()) {
logger.info("Looking for @ControllerAdvice: " + getApplicationContext());
}
// 返回使用了 @ControllerAdvice 注解的类的集合
List adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
// 根据类中的 order 排序
AnnotationAwareOrderComparator.sort(adviceBeans);
List
//参数解析器的查找顺序
private List getDefaultArgumentResolvers() {
List resolvers = new ArrayList<>();
// 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());
// 解析@ModelAttribute 注解的参数
resolvers.add(new ServletModelAttributeMethodProcessor(false));
resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
resolvers.add(new RequestHeaderMapMethodArgumentResolver());
resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
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());
resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
resolvers.add(new RedirectAttributesMethodArgumentResolver());
resolvers.add(new ModelMethodProcessor());
resolvers.add(new MapMethodProcessor());
resolvers.add(new ErrorsMethodArgumentResolver());
resolvers.add(new SessionStatusMethodArgumentResolver());
resolvers.add(new UriComponentsBuilderMethodArgumentResolver());
// Custom arguments
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}
// Catch-all
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
resolvers.add(new ServletModelAttributeMethodProcessor(true));
return resolvers;
}
有@InitBinder 注解的参数解析器
private List getDefaultInitBinderArgumentResolvers() {
List resolvers = new ArrayList<>();
// 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;
}
private List getDefaultReturnValueHandlers() {
List handlers = new ArrayList<>();
// Single-purpose return value types
handlers.add(new ModelAndViewMethodReturnValueHandler());
handlers.add(new ModelMethodProcessor());
handlers.add(new ViewMethodReturnValueHandler());
handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),
this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));
handlers.add(new StreamingResponseBodyReturnValueHandler());
handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
handlers.add(new HttpHeadersReturnValueHandler());
handlers.add(new CallableMethodReturnValueHandler());
handlers.add(new DeferredResultMethodReturnValueHandler());
handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));
// Annotation-based return value types
handlers.add(new ModelAttributeMethodProcessor(false));
handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
// Multi-purpose return value types
handlers.add(new ViewNameMethodReturnValueHandler());
handlers.add(new MapMethodProcessor());
// 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));
}
return handlers;
}
DispatcherServlet.doDispatch
-->AbstractHandlerMethodAdapter.handle
-->RequestMappingHandlerAdapter.handleInternal
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
checkRequest(request);
// Execute invokeHandlerMethod in synchronized block if required.
// 如果这个参数为true,且存在session,则会添加同步锁,当同一个session请求过来时,会等待前面的请求执行完
// 该参数默认为false,可以通过BeanPostProcessor(后置处理器实现)
// if("requestMappingHandlerAdapter".equals(beanName)){
// RequestMappingHandlerAdapter requestMappingHandlerAdapter = (RequestMappingHandlerAdapter) bean;
// requestMappingHandlerAdapter.setSynchronizeOnSession(true);
// log.debug("设置" + beanName +"的SynchronizeOnSession为true");
// }
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// No HttpSession available -> no mutex necessary
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// No synchronization on session demanded at all...
mav = invokeHandlerMethod(request, response, handlerMethod);
}
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}
else {
prepareResponse(response);
}
}
return mav;
}
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
//将request和response保存到webRequest中
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
//@InitBinder 处理
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
// model处理
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
//将 handlerMethod 中的参数设置到 invocableMethod 中
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
if (this.argumentResolvers != null) {
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
if (this.returnValueHandlers != null) {
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}
invocableMethod.setDataBinderFactory(binderFactory);
// parameterNameDiscoverer 参数名发现器
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
// flashMap 是存放重定向时,传递参数的map。把flashMap中的值设置到model中
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
//初始化model
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
// 在重定向的时候,是否忽略默认的model
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();
if (logger.isDebugEnabled()) {
logger.debug("Found concurrent result value [" + result + "]");
}
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
//执行请求
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
webRequest.requestCompleted();
}
}
//主要功能就是实现参数和String之间的类型转换,ArgumentResolver 在进行参数解析的过程也会用到,还有就是ModelFactory在更新model是也会用到
private WebDataBinderFactory getDataBinderFactory(HandlerMethod handlerMethod) throws Exception {
//获取处理器类的类型
Class> handlerType = handlerMethod.getBeanType();
//检查当前handlerType的@InitBinder方法是否已经在缓存中
Set methods = this.initBinderCache.get(handlerType);
if (methods == null) {
//如果不存在会重新获取一遍,如果类中没有@InitBinder方法,则返回空的Set,不是null,这样就可以根据 methods == null 判断是否调用过selectMethods
methods = MethodIntrospector.selectMethods(handlerType, INIT_BINDER_METHODS);
this.initBinderCache.put(handlerType, methods);
}
//定义保存initBinderMethods方法的临时变量
List initBinderMethods = new ArrayList<>();
//首先添加全局中的
this.initBinderAdviceCache.forEach((clazz, methodSet) -> {
if (clazz.isApplicableToBeanType(handlerType)) {
//根据beanType获取bean
Object bean = clazz.resolveBean();
for (Method method : methodSet) {
//创建 InvocableHandlerMethod ,将bean,method,initBinderArgumentResolvers,new DefaultDataBinderFactory(this.webBindingInitializer),parameterNameDiscoverer设置到新建的对象中
//webBindingInitializer 是创建 RequestMappingHandlerAdapter 对象的时候初始化的,为DataBinder提供全局的初始化
initBinderMethods.add(createInitBinderMethod(bean, method));
}
}
});
for (Method method : methods) {
Object bean = handlerMethod.getBean();
initBinderMethods.add(createInitBinderMethod(bean, method));
}
//返回的是 ServletRequestDataBinderFactory 类型的 WebDataBinderFactory
return createDataBinderFactory(initBinderMethods);
}
//主要功能1、在处理器具体处理之前对model进行初始化,2、处理完请求后对model参数进行更新
private ModelFactory getModelFactory(HandlerMethod handlerMethod, WebDataBinderFactory binderFactory) {
//获取SessionAttribute处理器,SessionAttributeStore是处理器工具
SessionAttributesHandler sessionAttrHandler = getSessionAttributesHandler(handlerMethod);
Class> handlerType = handlerMethod.getBeanType();
// 查找没有使用 @RequestMapping 但使用了 @ModelAttribute 的方法
// 其中全局的methods,在初始化的时候已经添加到modelAttributeCache
Set methods = this.modelAttributeCache.get(handlerType);
if (methods == null) {
methods = MethodIntrospector.selectMethods(handlerType, MODEL_ATTRIBUTE_METHODS);
this.modelAttributeCache.put(handlerType, methods);
}
List attrMethods = new ArrayList<>();
// Global methods first
this.modelAttributeAdviceCache.forEach((clazz, methodSet) -> {
if (clazz.isApplicableToBeanType(handlerType)) {
Object bean = clazz.resolveBean();
for (Method method : methodSet) {
//创建 InvocableHandlerMethod ,将bean,method,argumentResolvers,parameterNameDiscoverer,binderFactory(getDataBinderFactory方法获取的)设置到新建的对象中
attrMethods.add(createModelAttributeMethod(binderFactory, bean, method));
}
}
});
for (Method method : methods) {
Object bean = handlerMethod.getBean();
attrMethods.add(createModelAttributeMethod(binderFactory, bean, method));
}
return new ModelFactory(attrMethods, binderFactory, sessionAttrHandler);
}
// Create a new instance with the given {@code @ModelAttribute} methods.
public ModelFactory(@Nullable List handlerMethods,
WebDataBinderFactory binderFactory, SessionAttributesHandler attributeHandler) {
if (handlerMethods != null) {
for (InvocableHandlerMethod handlerMethod : handlerMethods) {
this.modelMethods.add(new ModelMethod(handlerMethod));
}
}
this.dataBinderFactory = binderFactory;
this.sessionAttributesHandler = attributeHandler;
}
private SessionAttributesHandler getSessionAttributesHandler(HandlerMethod handlerMethod) {
Class> handlerType = handlerMethod.getBeanType();
SessionAttributesHandler sessionAttrHandler = this.sessionAttributesHandlerCache.get(handlerType);
if (sessionAttrHandler == null) {
synchronized (this.sessionAttributesHandlerCache) {
sessionAttrHandler = this.sessionAttributesHandlerCache.get(handlerType);
if (sessionAttrHandler == null) {
sessionAttrHandler = new SessionAttributesHandler(handlerType, sessionAttributeStore);
this.sessionAttributesHandlerCache.put(handlerType, sessionAttrHandler);
}
}
}
return sessionAttrHandler;
}
//初始化具体包括三个部分
//1、将原来的(当前处理器先前已经保存的)SessionAttributes 中的值设置到model
//2、执行相应注释了@ModelAttributes的方法并将其值设置到model
//3、遍历既注释了@modelAttribute 又在@sessionAttributes注解中的参数,判断是否已经在 macContainer 里,如果没有就遍历所有的处理器的 SessionAttributes 获取保存,如果还没有就抛异常
public void initModel(NativeWebRequest request, ModelAndViewContainer container, HandlerMethod handlerMethod)
throws Exception {
//获取SessionAttributeHandler中保存的参数,并合并到mavContainer的model中
Map sessionAttributes = this.sessionAttributesHandler.retrieveAttributes(request);
container.mergeAttributes(sessionAttributes);
//执行 @ModelAttribute 的方法并将结果设置到model中
invokeModelAttributeMethods(request, container);
for (String name : findSessionAttributeArguments(handlerMethod)) {
if (!container.containsAttribute(name)) {
Object value = this.sessionAttributesHandler.retrieveAttribute(request, name);
if (value == null) {
throw new HttpSessionRequiredException("Expected session attribute '" + name + "'", name);
}
container.addAttribute(name, value);
}
}
}
private void invokeModelAttributeMethods(NativeWebRequest request, ModelAndViewContainer container)
throws Exception {
while (!this.modelMethods.isEmpty()) {
InvocableHandlerMethod modelMethod = getNextModelMethod(container).getHandlerMethod();
ModelAttribute ann = modelMethod.getMethodAnnotation(ModelAttribute.class);
Assert.state(ann != null, "No ModelAttribute annotation");
if (container.containsAttribute(ann.name())) {
//binding是注解的参数,默认为true,可以设置为false,阻止属性进行绑定
if (!ann.binding()) {
container.setBindingDisabled(ann.name());
}
continue;
}
//执行注解的方法
Object returnValue = modelMethod.invokeForRequest(request, container);
if (!modelMethod.isVoid()){
//获取保存的key的名称,如果@ModelAttribute 中已经写了value就用这个值,否则根据规则在取一个
String returnValueName = getNameForReturnValue(returnValue, modelMethod.getReturnType());
if (!ann.binding()) {
container.setBindingDisabled(returnValueName);
}
if (!container.containsAttribute(returnValueName)) {
container.addAttribute(returnValueName, returnValue);
}
}
}
}
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 {
// 如果有返回值,则执行返回值处理器方法
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
catch (Exception ex) {
if (logger.isTraceEnabled()) {
logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);
}
throw ex;
}
}
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));
}
//执行请求处理的方法,我们写的代码就是通过这个来执行的,这个方法会使用 ReflectionUtils.makeAccessible 强制将方法变为可调用的,即使是使用 private 也是可以被调用
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 {
// 获取到方法的参数
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);
// 如果参数在providedArgs中,则直接去值,否则继续(这个参数值是方法传入的),目前调用这个方法的方法,为传入参数
args[i] = resolveProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
// 判断参数解析器是否支持这个参数的解析
if (this.argumentResolvers.supportsParameter(parameter)) {
try {
args[i] = this.argumentResolvers.resolveArgument(
parameter, mavContainer, request, this.dataBinderFactory);
continue;
}
catch (Exception ex) {
if (logger.isDebugEnabled()) {
logger.debug(getArgumentResolutionErrorMessage("Failed to resolve", i), ex);
}
throw ex;
}
}
if (args[i] == null) {
throw new IllegalStateException("Could not resolve method parameter at index " +
parameter.getParameterIndex() + " in " + parameter.getExecutable().toGenericString() +
": " + getArgumentResolutionErrorMessage("No suitable resolver for", i));
}
}
return args;
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
return (getArgumentResolver(parameter) != null);
}
@Override
@Nullable
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
// 找到参数的解析器
HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
if (resolver == null) {
throw new IllegalArgumentException("Unknown parameter type [" + parameter.getParameterType().getName() + "]");
}
// 这里根据不同的参数解析器有不同的方法
return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
}
获取参数解析器
@Nullable
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
if (result == null) {
for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
if (logger.isTraceEnabled()) {
logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" +
parameter.getGenericParameterType() + "]");
}
if (methodArgumentResolver.supportsParameter(parameter)) {
result = methodArgumentResolver;
this.argumentResolverCache.put(parameter, result);
break;
}
}
}
return result;
}
@Override
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
//选择处理器
HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
if (handler == null) {
throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
}
// 根据不同的处理器执行其处理方法
handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
}
@Nullable
private HandlerMethodReturnValueHandler selectHandler(@Nullable Object value, MethodParameter returnType) {
boolean isAsyncValue = isAsyncReturnValue(value, returnType);
for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) {
if (isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler)) {
continue;
}
if (handler.supportsReturnType(returnType)) {
return handler;
}
}
return null;
}