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