SpringMVC源码-创建RequestMappingHandlerAdapter

一、RequestMappingHandlerAdapter

RequestMappingHandlerAdapter所属BeanDifinition的属性。

RequestMappingHandlerAdapter是将当前请求适配到@RequestMapping类型的Handler处理器。handler指的是Spring处理具体请求的某个Controller的方法。

HandlerAdapter

public interface HandlerAdapter {

/**
是否支持handle
 */
boolean supports(Object handler);

/**
 使用handle处理request
 */
@Nullable
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

/**
 * 与HttpServlet的getLastModified方法相同
 */
long getLastModified(HttpServletRequest request, Object handler);

}

HandlerAdapter指的是将当前请求适配到某个Handler的处理器。

HandlerAdapter的实现:

RequestMappingHandlerAdapter:将当前请求适配到@RequestMapping类型的Handler处理器。
HttpRequestHandlerAdapter:适配使用通用DispatcherServlet的HttpRequestHandler接口。
SimpleControllerHandlerAdapter:适配使用通用DispatcherServlet的Controller工作流接口。

二、实例化RequestMappingHandlerAdapter

RequestMappingHandlerAdapter

public RequestMappingHandlerAdapter() {
	this.messageConverters = new ArrayList<>(4);
	this.messageConverters.add(new ByteArrayHttpMessageConverter());
	this.messageConverters.add(new StringHttpMessageConverter());
	if (!shouldIgnoreXml) {
		try {
			this.messageConverters.add(new SourceHttpMessageConverter<>());
		}
		catch (Error err) {
			// Ignore when no TransformerFactory implementation is available
		}
	}
	this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
}

初始化messageConverters集合,并添加ByteArrayHttpMessageConverter,StringHttpMessageConverter和AllEncompassingFormHttpMessageConverter。如果shouldIgnoreXml为false则添加SourceHttpMessageConverter。

RequestMappingHandlerAdapter.afterPropertiesSet()

	public void afterPropertiesSet() {
	// Do this first, it may add ResponseBody advice beans
	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);
	}
}

1、调用initControllerAdviceCache设置@ModelAttribute,@InitBinder标注的方法,设置RequestBodyAdvice和ResponseBodyAdvice类型的bean。
2、如果argumentResolvers为null,getDefaultArgumentResolvers添加默认参数值处理器
3、如果initBinderArgumentResolvers为空,getDefaultInitBinderArgumentResolvers添加InitBinder参数处理器
4、如果returnValueHandlers为空,调用getDefaultReturnValueHandlers添加默认返回值处理器

RequestMappingHandlerAdapter.initControllerAdviceCache()

private void initControllerAdviceCache() {
	if (getApplicationContext() == null) {
		return;
	}

	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);
		}
		Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
		if (!attrMethods.isEmpty()) {
			this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
		}
		Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
		if (!binderMethods.isEmpty()) {
			this.initBinderAdviceCache.put(adviceBean, binderMethods);
		}
		if (RequestBodyAdvice.class.isAssignableFrom(beanType) || ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
			requestResponseBodyAdviceBeans.add(adviceBean);
		}
	}

	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");
		}
	}
}

1、findAnnotatedBeans在ApplicationContext查找@ControllerAdvice标注的bean,并以List返回
2、第一步的List,
如果bean没有@RequestMapping标注,有@ModelAttribute标注的Method,则将bean为key,Method集合(Set类型)为value加入modelAttributeAdviceCache。
如果bean有@InitBinder标注的方法则将bean为key,Method集合(Set类型)为value加入initBinderAdviceCache。
如果bean类型是RequestBodyAdvice或ResponseBodyAdvice则将bean加入requestResponseBodyAdviceBeans集合
3、如果requestResponseBodyAdviceBeans集合非空,则将requestResponseBodyAdviceBeans加入requestResponseBodyAdvice属性

RequestMappingHandlerAdapter.getDefaultArgumentResolvers()

private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
	List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(30);

	// 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 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());
	if (KotlinDetector.isKotlinPresent()) {
		resolvers.add(new ContinuationHandlerMethodArgumentResolver());
	}

	// Custom arguments
	if (getCustomArgumentResolvers() != null) {
		resolvers.addAll(getCustomArgumentResolvers());
	}

	// Catch-all
	resolvers.add(new PrincipalMethodArgumentResolver());
	resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
	resolvers.add(new ServletModelAttributeMethodProcessor(true));

	return resolvers;
}

添加方法参数处理器。

RequestMappingHandlerAdapter.getDefaultInitBinderArgumentResolvers()

private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() {
	List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(20);

	// 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 PrincipalMethodArgumentResolver());
	resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));

	return resolvers;
}

添加@InitBinder方法参数处理器

RequestMappingHandlerAdapter.getDefaultReturnValueHandlers

private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
	List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>(20);

	// 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 ServletModelAttributeMethodProcessor(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 ServletModelAttributeMethodProcessor(true));
	}

	return handlers;
}

添加返回值处理器。

posted @ 2022-11-03 20:53  shigp1  阅读(234)  评论(0编辑  收藏  举报