HandlerAdapter 组件
HandlerAdapter 处理器的适配器,因为spring mvc中的处理器是多变的,我们可以通过实现Controller或者HttpRequestHandler接口,也可以通过@RequestMapping注解将方法作为一个处理器,这就导致spring mvc不能直接处理handler,所以这时候就需要一个适配器,让他去执行处理
HandlerAdapter组件之HandlerAdapter接口
public interface HandlerAdapter {
//判断当前适配器是否支持该处理器
boolean supports(Object var1);
//执行Handler
@Nullable
ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
//返回请求最新的更新时间,如果不支持返回-1即可
long getLastModified(HttpServletRequest var1, Object var2);
}
HandlerAdapter接口总共只有三个方法,相对于来说还是很好理解
- supports方法就是判断当前适配器是否支持该处理器,因为handler是多变的,所以处理器的类型是object类型的
- handle方法就是去执行处理器
- getLastModified方法是Http协议相关的,这边就不多做介绍了
HandlerAdapter 接口的体系结构如下:
初始化过程
在DispatcherServlet.onRefresh()方法中初始化了HandlerAdapter组件
private void initHandlerAdapters(ApplicationContext context) {
this.handlerAdapters = null;
//默认情况下是this.detectAllHandlerAdapters=true,
//检测容器中所有的HandlerAdapter的bean,并对其进行排序
if (this.detectAllHandlerAdapters=) {
// Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
Map<String, HandlerAdapter的bean,并对其进行排序> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerAdapters = new ArrayList<>(matchingBeans.values());
// We keep HandlerAdapters in sorted order.
AnnotationAwareOrderComparator.sort(this.handlerAdapters);
}
}
else {
//this.detectAllHandlerAdapters=false的情况下,获取默认的名为handlerAdapter的bean
try {
HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
this.handlerAdapters = Collections.singletonList(ha);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerAdapter later.
}
}
//如果以上两种方式都没有获取到handlerAdapter的bean,则通过加载配置文件下的默认类
// 默认文件是DispatcherServlet.properties,
//org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
org.springframework.web.servlet.function.support.HandlerFunctionAdapter
// Ensure we have at least some HandlerAdapters, by registering
// default HandlerAdapters if no other adapters are found.
if (this.handlerAdapters == null) {
this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
if (logger.isTraceEnabled()) {
logger.trace("No HandlerAdapters declared for servlet '" + getServletName() +
"': using default strategies from DispatcherServlet.properties");
}
}
}
handlerAdapter的初始化只要分为以下几步
- 首先判断是否需要检测关于HandlerAdapter的所有bean,true的情况下会去检测容器中的所有bean并对其进行排序,false的情况下会去获取名为handlerAdapter的bean
- 如果以上两种方式都没有获取的handlerAdapter的bean,则去加载配置文件DispatcherServlet.properties中的 org.springframework.web.servlet.HandlerAdapter属性中所有的类
HttpRequestHandlerAdapter
public class HttpRequestHandlerAdapter implements HandlerAdapter {
//可以看出来supports的具体实现其实是很简单的,就是判断handler是否是HttpRequestHandler类型的
@Override
public boolean supports(Object handler) {
return (handler instanceof HttpRequestHandler);
}
//调用handleRequest方法执行的handler
@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
((HttpRequestHandler) handler).handleRequest(request, response);
return null;
}
@Override
public long getLastModified(HttpServletRequest request, Object handler) {
if (handler instanceof LastModified) {
return ((LastModified) handler).getLastModified(request);
}
return -1L;
}
}
SimpleContrllerHandlerAdapter
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof Controller);
}
@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return ((Controller) handler).handleRequest(request, response);
}
@Override
public long getLastModified(HttpServletRequest request, Object handler) {
if (handler instanceof LastModified) {
return ((LastModified) handler).getLastModified(request);
}
return -1L;
}
}
- SimpleControllerHandlerAdapter和HttpRequestHandlerAdapter的实现几乎是一样的,唯一的不同就是supports方法判断当前处理器是否是Controller类型的
AbstractHandlerMethodAdapter
AbstractHandlerMethodAdapter实现了HandlerAdapter和Ordered接口,继承了WebContentGenerator类
初始化
//最低优先级
private int order = Ordered.LOWEST_PRECEDENCE;
//调用了WebContentGenerator的构造方法,当参数为false的时候,表示表示不需要严格效验HttpMethod
public AbstractHandlerMethodAdapter() {
// no restriction of HTTP methods by default
super(false);
}
supports方法
//判断handler是否是HandlerMethod类型,调用supportsInternal方法
@Override
public final boolean supports方法,判断(Object handler) {
return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
}
/**
* Given a handler method, return whether or not this adapter can support it.
* @param handlerMethod the handler method to check
* @return whether or not this adapter can adapt the given method
*/
//具体实现交于子类
protected abstract boolean supportsInternal(HandlerMethod handlerMethod);
- 实现supports方法,判断handler是否是HandlerMethod类型,调用supportsInternal方法,supportsInternal方法交于子类去实现,目前子类只有RequestMappingHandlerAdapter,其实现是直接返回true
handler方法
@Override
@Nullable
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//调用handleInternal方法
return handleInternal(request, response, (HandlerMethod) handler);
}
/**
* Use the given handler method to handle the request.
* @param request current HTTP request
* @param response current HTTP response
* @param handlerMethod handler method to use. This object must have previously been passed to the
* {@link #supportsInternal(HandlerMethod)} this interface, which must have returned {@code true}.
* @return a ModelAndView object with the name of the view and the required model data,
* or {@code null} if the request has been handled directly
* @throws Exception in case of errors
*/
//交于其子类去实现
@Nullable
protected abstract ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception;
- handler 调用handleInternal方法,handleInternal方法交于其子类去实现
getLastModified方法
//调用的getLastModifiedInternal方法,getLastModifiedInternal方法交于其子类去实现
@Override
public final long getLastModified(HttpServletRequest request, Object handler) {
return getLastModifiedInternal(request, (HandlerMethod) handler);
}
/**
* Same contract as for {@link javax.servlet.http.HttpServlet#getLastModified(HttpServletRequest)}.
* @param request current HTTP request
* @param handlerMethod handler method to use
* @return the lastModified value for the given handler
*/
protected abstract long getLastModifiedInternal(HttpServletRequest request, HandlerMethod handlerMethod);
- 调用的getLastModifiedInternal方法,getLastModifiedInternal方法交于其子类去实现
AbstractHandlerMethodAdapter实现了HandlerAdapter中的三个方法,每一个方法都是调用自定义方法,而自定义的方法都是交于其子类去实现
RequestMappingHandlerAdapter
构造方法
@Nullable
private List<HandlerMethodArgumentResolver> customArgumentResolvers;
@Nullable
private HandlerMethodArgumentResolverComposite argumentResolvers;
@Nullable
private HandlerMethodArgumentResolverComposite initBinderArgumentResolvers;
@Nullable
private List<HandlerMethodReturnValueHandler> customReturnValueHandlers;
@Nullable
private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
@Nullable
private List<ModelAndViewResolver> modelAndViewResolvers;
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
private List<HttpMessageConverter<?>> messageConverters;
private List<Object> requestResponseBodyAdvice = new ArrayList<>();
@Nullable
private WebBindingInitializer webBindingInitializer;
private AsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor("MvcAsync");
@Nullable
private Long asyncRequestTimeout;
private CallableProcessingInterceptor[] callableInterceptors = new CallableProcessingInterceptor[0];
private DeferredResultProcessingInterceptor[] deferredResultInterceptors = new DeferredResultProcessingInterceptor[0];
private ReactiveAdapterRegistry reactiveAdapterRegistry = ReactiveAdapterRegistry.getSharedInstance();
private boolean ignoreDefaultModelOnRedirect = false;
private int cacheSecondsForSessionAttributeHandlers = 0;
private boolean synchronizeOnSession = false;
private SessionAttributeStore sessionAttributeStore = new DefaultSessionAttributeStore();
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
@Nullable
private ConfigurableBeanFactory beanFactory;
//缓存
private final Map<Class<?>, SessionAttributesHandler> sessionAttributesHandlerCache = new ConcurrentHashMap<>(64);
private final Map<Class<?>, Set<Method>> initBinderCache = new ConcurrentHashMap<>(64);
private final Map<ControllerAdviceBean, Set<Method>> initBinderAdviceCache = new LinkedHashMap<>();
private final Map<Class<?>, Set<Method>> modelAttributeCache = new ConcurrentHashMap<>(64);
private final Map<ControllerAdviceBean, Set<Method>> modelAttributeAdviceCache = new LinkedHashMap<>();
//添加了消息转换器
public RequestMappingHandlerAdapter() {
this.messageConverters = new ArrayList<>(4);
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter());
try {
this.messageConverters.add(new SourceHttpMessageConverter<>());
}
catch (Error err) {
// Ignore when no TransformerFactory implementation is available
}
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
}
public AllEncompassingFormHttpMessageConverter() {
try {
addPartConverter(new SourceHttpMessageConverter<>());
}
catch (Error err) {
// Ignore when no TransformerFactory implementation is available
}
if (jaxb2Present && !jackson2XmlPresent) {
addPartConverter(new Jaxb2RootElementHttpMessageConverter());
}
if (jackson2Present) {
addPartConverter(new MappingJackson2HttpMessageConverter());
}
else if (gsonPresent) {
addPartConverter(new GsonHttpMessageConverter());
}
else if (jsonbPresent) {
addPartConverter(new JsonbHttpMessageConverter());
}
if (jackson2XmlPresent) {
addPartConverter(new MappingJackson2XmlHttpMessageConverter());
}
if (jackson2SmilePresent) {
addPartConverter(new MappingJackson2SmileHttpMessageConverter());
}
}
以上有许多属性,这边只介绍几个简单的属性
-
HandlerMethodArgumentResolverComposite argumentResolvers : 参数解析组合对象
-
HandlerMethodReturnValueHandlerComposite returnValueHandlers : 返回参数处理器组合对象
-
List<HttpMessageConverter<?>> messageConverters : HTTP消息转换器集合
-
List requestResponseBodyAdvice :requestResponseBodyAdvice 对象集合 从以上代码可以看出构造方法中初始化了多种消息转换器
afterPropertiesSet方法 RequestMappingHandler实现了InitializingBean接口,所以在bean初始化后一定会执行afterPropertiesSet方法
@Override
public void afterPropertiesSet() {
// Do this first, it may add ResponseBody advice beans
//初始化ControllerAdvice
initControllerAdviceCache();
//初始化argumentResolvers参数解析对象
if (this.argumentResolvers == null) {
List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
初始化initBinderArgumentResolver
if (this.initBinderArgumentResolvers == null) {
List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
//初始化returnValueHandler
if (this.returnValueHandlers == null) {
List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
}
}
* 调用initControllerAdviceCache()初始化ControllerAdvice相关
* 初始化argumentResolvers属性,调用getDefaultArgumentResolvers()获取到默认的参数解析对象数组
* 初始化initBinderArgumentResolvers属性,调用getDefaultInitBinderArgumentResolvers()获取到HandlerMethodArgumentResolver对象数组
* 初始化returnValueHandlers属性,调用getDefaultReturnValueHandlers获取到HandlerMethodReturnValueHandler(返回参数处理器集合)
* getDefaultArgumentResolvers()和getDefaultInitBinderArgumentResolvers()以及getDefaultReturnValueHandlers()方法都没有什么好说的,都是初始化一些默认的对象,然后封装成集合返回
**initControllerAdviceCache**
private void initControllerAdviceCache() {
if (getApplicationContext() == null) {
return;
}
//获取到所有带有@ControllerAdvice注解的的bean,并进行排序
List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
AnnotationAwareOrderComparator.sort(adviceBeans);
List<Object> requestResponseBodyAdviceBeans = new ArrayList<>();
//遍历到获取到的bean
for (ControllerAdviceBean adviceBean : adviceBeans) {
Class<?> beanType = adviceBean.getBeanType();
if (beanType == null) {
throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
}
//扫描带有'@ModelAttribute'注解却没有带有@RequestMapping注解的bean的方法,添加到modelAttributeAdviceCache属性中
//该方法用于处理执行方法前的Model
Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
if (!attrMethods.isEmpty()) {
this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
}
//扫描带有'@InitBinder'注解的方法,添加到initBinderAdviceCache属性中
//该类方法用于方法执行前初始化数据绑定器
Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
if (!binderMethods.isEmpty()) {
this.initBinderAdviceCache.put(adviceBean, binderMethods);
}
//如果是RequestBodyAdvice的子类则添加到requestResponseBodyAdviceBeans中
if (RequestBodyAdvice.class.isAssignableFrom(beanType)) {
requestResponseBodyAdviceBeans.add(adviceBean);
}
//如果是ResponseBodyAdvice的子类则添加到requestResponseBodyAdviceBeans中
if (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");
}
}
}
* initControllerAdviceCache()方法中首先会去扫描带有@ControllerAdvice注解的bean,封装成一个ControllerAdviceBean类型的集合
* 遍历所有的ControllerAdviceBean对象,将带有'@ModelAttribute'注解却没有带有@RequestMapping注解的bean的方法,添加到modelAttributeAdviceCache属性中
* 遍历所有带有'@InitBinder'注解的方法,添加到initBinderAdviceCache属性中
* 判断ControllerAdviceBean是否是RequestBodyAdvice子类或者ResponseBodyAdvice子类,将其添加到requestResponseBodyAdviceBeans中,最后在将requestResponseBodyAdviceBeans中对象全部添加的requestResponseBodyAdvice中
**supportsInternal方法** supportsInternal方法中直接返回的true,这个就没有什么好说的了
@Override
protected boolean supportsInternal(HandlerMethod handlerMethod) {
return true;
}
**getLastModifiedInternal方法** getLastModifiedInternal方法中直接返回的-1,这个也没有什么好说的
@Override
protected long getLastModifiedInternal(HttpServletRequest request, HandlerMethod handlerMethod) {
return -1;
}
**handleInternal**
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
// <1> 校验请求(HttpMethod 和 Session 的校验)
checkRequest(request);
// Execute invokeHandlerMethod in synchronized block if required.
// 同步相同 Session 的逻辑,默认情况false
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
// 获取Session的锁对象
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;
}