springmvc源碼解析之@EnableWebMvc五

說在前面web

本次主要介紹springmvc配置解析。關注「天河聊架構」微信公衆號有更多精彩。spring

 

springmvc配置解析緩存

@EnableWebMvc這個註解幹了什麼,初始化HandlerExceptionResolver微信

進入到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#handlerExceptionResolversession

@Bean
   public HandlerExceptionResolver handlerExceptionResolver() {
//    建立HandlerExceptionResolver
      List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<HandlerExceptionResolver>();
      configureHandlerExceptionResolvers(exceptionResolvers);
      if (exceptionResolvers.isEmpty()) {
//       添加默認的HandlerExceptionResolvers -》
         addDefaultHandlerExceptionResolvers(exceptionResolvers);
      }
      extendHandlerExceptionResolvers(exceptionResolvers);
      HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
      composite.setOrder(0);
      composite.setExceptionResolvers(exceptionResolvers);
      return composite;
   }

進入到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addDefaultHandlerExceptionResolvers架構

protected final void addDefaultHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
//    建立ExceptionHandlerExceptionResolver
      ExceptionHandlerExceptionResolver exceptionHandlerResolver = createExceptionHandlerExceptionResolver();
//    設置媒體類型管理器 -》
      exceptionHandlerResolver.setContentNegotiationManager(mvcContentNegotiationManager());
//    設置消息轉換器 -》
      exceptionHandlerResolver.setMessageConverters(getMessageConverters());
//    設置參數解析器
      exceptionHandlerResolver.setCustomArgumentResolvers(getArgumentResolvers());
//    設置returnHandlers -》
      exceptionHandlerResolver.setCustomReturnValueHandlers(getReturnValueHandlers());
      if (jackson2Present) {
//       設置JsonViewResponseBodyAdvice
         exceptionHandlerResolver.setResponseBodyAdvice(
               Collections.<ResponseBodyAdvice<?>>singletonList(new JsonViewResponseBodyAdvice()));
      }
      exceptionHandlerResolver.setApplicationContext(this.applicationContext);
//    exceptionHandlerResolver 配置加載 -》
      exceptionHandlerResolver.afterPropertiesSet();
      exceptionResolvers.add(exceptionHandlerResolver);
//    建立ResponseStatusExceptionResolver
      ResponseStatusExceptionResolver responseStatusResolver = new ResponseStatusExceptionResolver();
      responseStatusResolver.setMessageSource(this.applicationContext);
      exceptionResolvers.add(responseStatusResolver);
//    建立DefaultHandlerExceptionResolver
      exceptionResolvers.add(new DefaultHandlerExceptionResolver());
   }

進入到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#mvcContentNegotiationManagermvc

@Bean
   public ContentNegotiationManager mvcContentNegotiationManager() {
      if (this.contentNegotiationManager == null) {
//       初始化媒體類型管理器
         ContentNegotiationConfigurer configurer = new ContentNegotiationConfigurer(this.servletContext);
//       設置默認類型 -》
         configurer.mediaTypes(getDefaultMediaTypes());
//       配置媒體類型管理器 -》
         configureContentNegotiation(configurer);
//       構建媒體類型管理器 -》
         this.contentNegotiationManager = configurer.buildContentNegotiationManager();
      }
      return this.contentNegotiationManager;
   }

這裏前面介紹過了。app

往上返回到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getMessageConverterside

protected final List<HttpMessageConverter<?>> getMessageConverters() {
      if (this.messageConverters == null) {
         this.messageConverters = new ArrayList<HttpMessageConverter<?>>();
//       配置消息轉換器 -》
         configureMessageConverters(this.messageConverters);
         if (this.messageConverters.isEmpty()) {
//          添加默認http消息轉換器 -》
            addDefaultHttpMessageConverters(this.messageConverters);
         }
//       擴展消息轉換器
         extendMessageConverters(this.messageConverters);
      }
      return this.messageConverters;
   }

這裏前面介紹過了。ui

往上返回到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getReturnValueHandlers

protected final List<HandlerMethodReturnValueHandler> getReturnValueHandlers() {
   if (this.returnValueHandlers == null) {
      this.returnValueHandlers = new ArrayList<HandlerMethodReturnValueHandler>();
      addReturnValueHandlers(this.returnValueHandlers);
   }
   return this.returnValueHandlers;
}

往上返回到這個方法org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#afterPropertiesSet

@Override
   public void afterPropertiesSet() {
      // Do this first, it may add ResponseBodyAdvice beans 初始化異常handler通知緩存 -》
      initExceptionHandlerAdviceCache();
      if (this.argumentResolvers == null) {
//       獲取默認的參數解析器-》
         List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
         this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
      }
      if (this.returnValueHandlers == null) {
//       獲取默認的ReturnValueHandlers -》
         List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
         this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
      }
   }

進入到這個方法org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#initExceptionHandlerAdviceCache

private void initExceptionHandlerAdviceCache() {
      if (getApplicationContext() == null) {
         return;
      }
      if (logger.isDebugEnabled()) {
         logger.debug("Looking for exception mappings: " + getApplicationContext());
      }

//    查找@ControllerAdvice註解的controller -》
      List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
      AnnotationAwareOrderComparator.sort(adviceBeans);
      for (ControllerAdviceBean adviceBean : adviceBeans) {
         ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(adviceBean.getBeanType());
         if (resolver.hasExceptionMappings()) {
            this.exceptionHandlerAdviceCache.put(adviceBean, resolver);
            if (logger.isInfoEnabled()) {
               logger.info("Detected @ExceptionHandler methods in " + adviceBean);
            }
         }
         if (ResponseBodyAdvice.class.isAssignableFrom(adviceBean.getBeanType())) {
            this.responseBodyAdvice.add(adviceBean);
            if (logger.isInfoEnabled()) {
               logger.info("Detected ResponseBodyAdvice implementation in " + adviceBean);
            }
         }
      }
   }

進入到這個方法org.springframework.web.method.ControllerAdviceBean#findAnnotatedBeans

public static List<ControllerAdviceBean> findAnnotatedBeans(ApplicationContext applicationContext) {
   List<ControllerAdviceBean> beans = new ArrayList<ControllerAdviceBean>();
   for (String name : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, Object.class)) {
      if (applicationContext.findAnnotationOnBean(name, ControllerAdvice.class) != null) {
         beans.add(new ControllerAdviceBean(name, applicationContext));
      }
   }
   return beans;
}

往上返回到這個方法org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#getDefaultArgumentResolvers

protected List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
      List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();
      // Annotation-based argument resolution
//    從session中解析參數解析器@SessionAttribute
      resolvers.add(new SessionAttributeMethodArgumentResolver());
//    從request中解析參數解析器@RequestAttribute
      resolvers.add(new RequestAttributeMethodArgumentResolver());
      // Type-based argument resolution
//    基於servletRequets的參數解析器
      resolvers.add(new ServletRequestMethodArgumentResolver());
//    基於servletResponse的參數解析器
      resolvers.add(new ServletResponseMethodArgumentResolver());
//    重定向綁定參數解析器
      resolvers.add(new RedirectAttributesMethodArgumentResolver());
//    從model中解析參數解析器
      resolvers.add(new ModelMethodProcessor());
      // Custom arguments 自定義參數解析器
      if (getCustomArgumentResolvers() != null) {
         resolvers.addAll(getCustomArgumentResolvers());
      }

      return resolvers;
   }

往上返回到這個方法org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#getDefaultReturnValueHandlers

protected List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
      List<HandlerMethodReturnValueHandler> handlers = new ArrayList<HandlerMethodReturnValueHandler>();
      // Single-purpose return value types
//    基於modelAndView返回值解析器
      handlers.add(new ModelAndViewMethodReturnValueHandler());
//    基於model的返回值解析器
      handlers.add(new ModelMethodProcessor());
//    基於view的返回值解析器
      handlers.add(new ViewMethodReturnValueHandler());
//    基於HttpEntity的返回值解析器
      handlers.add(new HttpEntityMethodProcessor(
            getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice));
      // Annotation-based return value types
//    基於@ModelAttribute屬性方法的返回值解析器
      handlers.add(new ModelAttributeMethodProcessor(false));
//    基於@RequestBody和@ResponseBody註解方法的參數解析器
      handlers.add(new RequestResponseBodyMethodProcessor(
            getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice));
      // Multi-purpose return value types
//    基於視圖名字的返回值解析器
      handlers.add(new ViewNameMethodReturnValueHandler());
//    基於map的返回值解析器
      handlers.add(new MapMethodProcessor());
      // Custom return value types 自定義返回值解析器
      if (getCustomReturnValueHandlers() != null) {
         handlers.addAll(getCustomReturnValueHandlers());
      }

      // Catch-all
//    基於@ModelAttribute註解方法的解析器
      handlers.add(new ModelAttributeMethodProcessor(true));
      return handlers;
   }

往上返回到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#handlerExceptionResolver

 

 

說到最後

本次源碼解析僅表明我的觀點,僅供參考。

相關文章
相關標籤/搜索