1. 程式人生 > >springmvc原始碼解析MvcNamespaceHandler之 <mvc:annotation-driven/>一

springmvc原始碼解析MvcNamespaceHandler之 <mvc:annotation-driven/>一

開發十年,就只剩下這套架構體系了! >>>   

說在前面

本次主要介紹springmvc配置解析。

 

springmvc配置解析

本次介紹MvcNamespaceHandler。

public void init() {
   registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
   registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());
   registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
   registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());
   registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());
   registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser());
   registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser());
   registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());
   registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());
   registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());
   registerBeanDefinitionParser("velocity-configurer", new VelocityConfigurerBeanDefinitionParser());
   registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());
   registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());
   registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());
}

進入到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#parse

接下來介紹這個標籤<mvc:annotation-driven/>原始碼解析,找到這個類org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser,這個標籤做了什麼事情呢。

預設註冊了RequestMappingHandlerMapping、BeanNameUrlHandlerMapping、RequestMappingHandlerAdapter、HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、ExceptionHandlerExceptionResolver、ResponseStatusExceptionResolver、DefaultHandlerExceptionResolver這些元件,這些元件是幹什麼的第一篇文章有介紹。

找到這個org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#parse,由於之前spring原始碼解析的鋪墊,我們知道解析xml標籤bean定義到beanFactory會執行這個方法。載入xml解析bean定義註冊到beanFactory這裡不做詳細介紹,大家可以詳約之前的spring原始碼解析文章。

@Override
   public BeanDefinition parse(Element element, ParserContext context) {
      Object source = context.extractSource(element);
//    獲取XmlReaderContext
      XmlReaderContext readerContext = context.getReaderContext();
      CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
      context.pushContainingComponent(compDefinition);
//    請求、響應格式管理器 ->
      RuntimeBeanReference contentNegotiationManager = getContentNegotiationManager(element, source, context);
//    註冊RequestMappingHandlerMapping bean定義
      RootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class);
      handlerMappingDef.setSource(source);
      handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//    設定順序,預設是0
      handlerMappingDef.getPropertyValues().add("order", 0);
//    新增依賴bean定義
      handlerMappingDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
//    是否開啟矩陣變數查詢
      if (element.hasAttribute("enable-matrix-variables")) {
         Boolean enableMatrixVariables = Boolean.valueOf(element.getAttribute("enable-matrix-variables"));
         handlerMappingDef.getPropertyValues().add("removeSemicolonContent", !enableMatrixVariables);
      }
      else if (element.hasAttribute("enableMatrixVariables")) {
         Boolean enableMatrixVariables = Boolean.valueOf(element.getAttribute("enableMatrixVariables"));
         handlerMappingDef.getPropertyValues().add("removeSemicolonContent", !enableMatrixVariables);
      }

//    ->
      configurePathMatchingProperties(handlerMappingDef, element, context);
//    註冊RequestMappingHandlerMapping bean定義
      readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME , handlerMappingDef);
//    註冊跨域支援bean定義 ->
      RuntimeBeanReference corsRef = MvcNamespaceUtils.registerCorsConfigurations(null, context, source);
      handlerMappingDef.getPropertyValues().add("corsConfigurations", corsRef);
//    型別轉換服務bean定義解析
      RuntimeBeanReference conversionService = getConversionService(element, source, context);
//    validator bean定義解析 ->
      RuntimeBeanReference validator = getValidator(element, source, context);
//    解析訊息編碼解析器bean定義 ->
      RuntimeBeanReference messageCodesResolver = getMessageCodesResolver(element);
      RootBeanDefinition bindingDef = new RootBeanDefinition(ConfigurableWebBindingInitializer.class);
      bindingDef.setSource(source);
      bindingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
      bindingDef.getPropertyValues().add("conversionService", conversionService);
      bindingDef.getPropertyValues().add("validator", validator);
      bindingDef.getPropertyValues().add("messageCodesResolver", messageCodesResolver);
//    獲取訊息轉換器 ->
      ManagedList<?> messageConverters = getMessageConverters(element, source, context);
//    獲取引數解析器 ->
      ManagedList<?> argumentResolvers = getArgumentResolvers(element, context);
//    獲取返回值handler ->
      ManagedList<?> returnValueHandlers = getReturnValueHandlers(element, context);
//    獲取非同步超時時間 ->
      String asyncTimeout = getAsyncTimeout(element);
//    獲取非同步任務執行器 ->
      RuntimeBeanReference asyncExecutor = getAsyncExecutor(element);
//    獲取有返回值的攔截器
      ManagedList<?> callableInterceptors = getCallableInterceptors(element, source, context);
//    獲取延遲結果攔截器 ->
      ManagedList<?> deferredResultInterceptors = getDeferredResultInterceptors(element, source, context);
//    註冊RequestMappingHandlerAdapter bean定義
      RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class);
      handlerAdapterDef.setSource(source);
      handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
      handlerAdapterDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
      handlerAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
      handlerAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
//    新增json請求通知處理器JsonViewRequestBodyAdvice ->
      addRequestBodyAdvice(handlerAdapterDef);
//    新增json響應通知處理器JsonViewResponseBodyAdvice ->
      addResponseBodyAdvice(handlerAdapterDef);
//    重定向操作是否預設不帶引數
      if (element.hasAttribute("ignore-default-model-on-redirect")) {
         Boolean ignoreDefaultModel = Boolean.valueOf(element.getAttribute("ignore-default-model-on-redirect"));
         handlerAdapterDef.getPropertyValues().add("ignoreDefaultModelOnRedirect", ignoreDefaultModel);
      }
      else if (element.hasAttribute("ignoreDefaultModelOnRedirect")) {
         // "ignoreDefaultModelOnRedirect" spelling is deprecated
         Boolean ignoreDefaultModel = Boolean.valueOf(element.getAttribute("ignoreDefaultModelOnRedirect"));
         handlerAdapterDef.getPropertyValues().add("ignoreDefaultModelOnRedirect", ignoreDefaultModel);
      }

      if (argumentResolvers != null) {
         handlerAdapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
      }
      if (returnValueHandlers != null) {
         handlerAdapterDef.getPropertyValues().add("customReturnValueHandlers", returnValueHandlers);
      }
      if (asyncTimeout != null) {
//       解析非同步請求超時時間
         handlerAdapterDef.getPropertyValues().add("asyncRequestTimeout", asyncTimeout);
      }
      if (asyncExecutor != null) {
//       註冊非同步執行緒池
         handlerAdapterDef.getPropertyValues().add("taskExecutor", asyncExecutor);
      }

      handlerAdapterDef.getPropertyValues().add("callableInterceptors", callableInterceptors);
      handlerAdapterDef.getPropertyValues().add("deferredResultInterceptors", deferredResultInterceptors);
      readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME , handlerAdapterDef);
      RootBeanDefinition uriContributorDef =
            new RootBeanDefinition(CompositeUriComponentsContributorFactoryBean.class);
      uriContributorDef.setSource(source);
      uriContributorDef.getPropertyValues().addPropertyValue("handlerAdapter", handlerAdapterDef);
      uriContributorDef.getPropertyValues().addPropertyValue("conversionService", conversionService);
      String uriContributorName = MvcUriComponentsBuilder.MVC_URI_COMPONENTS_CONTRIBUTOR_BEAN_NAME;
      readerContext.getRegistry().registerBeanDefinition(uriContributorName, uriContributorDef);
//    註冊轉換服務攔截器
      RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class);
      csInterceptorDef.setSource(source);
      csInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, conversionService);
      RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
      mappedInterceptorDef.setSource(source);
      mappedInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
      mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, (Object) null);
      mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, csInterceptorDef);
      String mappedInterceptorName = readerContext.registerWithGeneratedName(mappedInterceptorDef);
//    註冊異常請求解析器bean定義
      RootBeanDefinition methodExceptionResolver = new RootBeanDefinition(ExceptionHandlerExceptionResolver.class);
      methodExceptionResolver.setSource(source);
      methodExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
      methodExceptionResolver.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
      methodExceptionResolver.getPropertyValues().add("messageConverters", messageConverters);
      methodExceptionResolver.getPropertyValues().add("order", 0);
//    新增json響應通知處理器JsonViewResponseBodyAdvice
      addResponseBodyAdvice(methodExceptionResolver);
      if (argumentResolvers != null) {
         methodExceptionResolver.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
      }
      if (returnValueHandlers != null) {
         methodExceptionResolver.getPropertyValues().add("customReturnValueHandlers", returnValueHandlers);
      }
      String methodExResolverName = readerContext.registerWithGeneratedName(methodExceptionResolver);
//    註冊響應狀態碼異常解析器bean定義
      RootBeanDefinition statusExceptionResolver = new RootBeanDefinition(ResponseStatusExceptionResolver.class);
      statusExceptionResolver.setSource(source);
      statusExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
      statusExceptionResolver.getPropertyValues().add("order", 1);
      String statusExResolverName = readerContext.registerWithGeneratedName(statusExceptionResolver);
//    註冊預設異常處理器bean定義
      RootBeanDefinition defaultExceptionResolver = new RootBeanDefinition(DefaultHandlerExceptionResolver.class);
      defaultExceptionResolver.setSource(source);
      defaultExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
      defaultExceptionResolver.getPropertyValues().add("order", 2);
      String defaultExResolverName = readerContext.registerWithGeneratedName(defaultExceptionResolver);
      context.registerComponent(new BeanComponentDefinition(handlerMappingDef, HANDLER_MAPPING_BEAN_NAME));
      context.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME));
      context.registerComponent(new BeanComponentDefinition(uriContributorDef, uriContributorName));
      context.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, mappedInterceptorName));
      context.registerComponent(new BeanComponentDefinition(methodExceptionResolver, methodExResolverName));
      context.registerComponent(new BeanComponentDefinition(statusExceptionResolver, statusExResolverName));
      context.registerComponent(new BeanComponentDefinition(defaultExceptionResolver, defaultExResolverName));
      // Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off" 註冊預設bean定義元件 ->
      MvcNamespaceUtils.registerDefaultComponents(context, source);
      context.popAndRegisterContainingComponent();
      return null;
   }

進入到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getContentNegotiationManager

private RuntimeBeanReference getContentNegotiationManager(Element element, Object source, ParserContext context) {
      RuntimeBeanReference beanRef;
//    content-negotiation-manager 標籤屬性
      if (element.hasAttribute("content-negotiation-manager")) {
         String name = element.getAttribute("content-negotiation-manager");
         beanRef = new RuntimeBeanReference(name);
      }
      else {
         RootBeanDefinition factoryBeanDef = new RootBeanDefinition(ContentNegotiationManagerFactoryBean.class);
         factoryBeanDef.setSource(source);
         factoryBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//       新增預設的mediaTypes ->
         factoryBeanDef.getPropertyValues().add("mediaTypes", getDefaultMediaTypes());
         String name = CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;
//       註冊mvcContentNegotiationManager bean定義
         context.getReaderContext().getRegistry().registerBeanDefinition(name , factoryBeanDef);
//       祖冊元件
         context.registerComponent(new BeanComponentDefinition(factoryBeanDef, name));
         beanRef = new RuntimeBeanReference(name);
      }
      return beanRef;
   }

進入到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getDefaultMediaTypes

private Properties getDefaultMediaTypes() {
      Properties defaultMediaTypes = new Properties();
      if (romePresent) {
         defaultMediaTypes.put("atom", MediaType.APPLICATION_ATOM_XML_VALUE);
         defaultMediaTypes.put("rss", MediaType.APPLICATION_RSS_XML_VALUE);
      }
//    xml型別 jaxb jackson
      if (jaxb2Present || jackson2XmlPresent) {
         defaultMediaTypes.put("xml", MediaType.APPLICATION_XML_VALUE);
      }
//    json型別 jackson gson
      if (jackson2Present || gsonPresent) {
         defaultMediaTypes.put("json", MediaType.APPLICATION_JSON_VALUE);
      }
      return defaultMediaTypes;
   }

往上返回到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#configurePathMatchingProperties

private void configurePathMatchingProperties(
         RootBeanDefinition handlerMappingDef, Element element, ParserContext context) {
// 路徑規則檔案配置
      Element pathMatchingElement = DomUtils.getChildElementByTagName(element, "path-matching");
      if (pathMatchingElement != null) {
         Object source = context.extractSource(element);
//       字尾
         if (pathMatchingElement.hasAttribute("suffix-pattern")) {
            Boolean useSuffixPatternMatch = Boolean.valueOf(pathMatchingElement.getAttribute("suffix-pattern"));
            handlerMappingDef.getPropertyValues().add("useSuffixPatternMatch", useSuffixPatternMatch);
         }
//       是否支援混合檢視
         if (pathMatchingElement.hasAttribute("trailing-slash")) {
            Boolean useTrailingSlashMatch = Boolean.valueOf(pathMatchingElement.getAttribute("trailing-slash"));
            handlerMappingDef.getPropertyValues().add("useTrailingSlashMatch", useTrailingSlashMatch);
         }
//       是否只註冊字首
         if (pathMatchingElement.hasAttribute("registered-suffixes-only")) {
            Boolean useRegisteredSuffixPatternMatch = Boolean.valueOf(pathMatchingElement.getAttribute("registered-suffixes-only"));
            handlerMappingDef.getPropertyValues().add("useRegisteredSuffixPatternMatch", useRegisteredSuffixPatternMatch);
         }

//       註冊path解析類
         RuntimeBeanReference pathHelperRef = null;
         if (pathMatchingElement.hasAttribute("path-helper")) {
            pathHelperRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-helper"));
         }
//       ->
         pathHelperRef = MvcNamespaceUtils.registerUrlPathHelper(pathHelperRef, context, source);
         handlerMappingDef.getPropertyValues().add("urlPathHelper", pathHelperRef);
         RuntimeBeanReference pathMatcherRef = null;
//       註冊路徑匹配器
         if (pathMatchingElement.hasAttribute("path-matcher")) {
            pathMatcherRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-matcher"));
         }
//       ->
         pathMatcherRef = MvcNamespaceUtils.registerPathMatcher(pathMatcherRef, context, source);
         handlerMappingDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
      }
   }

進入到這個方法org.springframework.web.servlet.config.MvcNamespaceUtils#registerUrlPathHelper

public static RuntimeBeanReference registerUrlPathHelper(
         RuntimeBeanReference urlPathHelperRef, ParserContext parserContext, Object source) {

      if (urlPathHelperRef != null) {
         if (parserContext.getRegistry().isAlias(URL_PATH_HELPER_BEAN_NAME)) {
            parserContext.getRegistry().removeAlias(URL_PATH_HELPER_BEAN_NAME);
         }
//       註冊mvcUrlPathHelper別名
         parserContext.getRegistry().registerAlias(urlPathHelperRef.getBeanName(), URL_PATH_HELPER_BEAN_NAME);
      }
      else if (!parserContext.getRegistry().isAlias(URL_PATH_HELPER_BEAN_NAME)
            && !parserContext.getRegistry().containsBeanDefinition(URL_PATH_HELPER_BEAN_NAME)) {
         RootBeanDefinition urlPathHelperDef = new RootBeanDefinition(UrlPathHelper.class);
         urlPathHelperDef.setSource(source);
         urlPathHelperDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//       註冊mvcUrlPathHelper bean定義
         parserContext.getRegistry().registerBeanDefinition(URL_PATH_HELPER_BEAN_NAME, urlPathHelperDef);
         parserContext.registerComponent(new BeanComponentDefinition(urlPathHelperDef, URL_PATH_HELPER_BEAN_NAME));
      }
      return new RuntimeBeanReference(URL_PATH_HELPER_BEAN_NAME);
   }

往上返回到這個方法org.springframework.web.servlet.config.MvcNamespaceUtils#registerPathMatcher

public static RuntimeBeanReference registerPathMatcher(
         RuntimeBeanReference pathMatcherRef, ParserContext parserContext, Object source) {

      if (pathMatcherRef != null) {
         if (parserContext.getRegistry().isAlias(PATH_MATCHER_BEAN_NAME)) {
            parserContext.getRegistry().removeAlias(PATH_MATCHER_BEAN_NAME);
         }
//       註冊別名mvcPathMatcher
         parserContext.getRegistry().registerAlias(pathMatcherRef.getBeanName(), PATH_MATCHER_BEAN_NAME);
      }
      else if (!parserContext.getRegistry().isAlias(PATH_MATCHER_BEAN_NAME)
            && !parserContext.getRegistry().containsBeanDefinition(PATH_MATCHER_BEAN_NAME)) {
         RootBeanDefinition pathMatcherDef = new RootBeanDefinition(AntPathMatcher.class);
         pathMatcherDef.setSource(source);
         pathMatcherDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//       註冊mvcPathMatcher bean定義
         parserContext.getRegistry().registerBeanDefinition(PATH_MATCHER_BEAN_NAME, pathMatcherDef);
         parserContext.registerComponent(new BeanComponentDefinition(pathMatcherDef, PATH_MATCHER_BEAN_NAME));
      }
      return new RuntimeBeanReference(PATH_MATCHER_BEAN_NAME);
   }

往上返回到這個方法org.springframework.web.servlet.config.MvcNamespaceUtils#registerCorsConfigurations

public static RuntimeBeanReference registerCorsConfigurations(
         Map<String, CorsConfiguration> corsConfigurations, ParserContext context, Object source) {

//    mvcCorsConfigurations 跨域支援bean定義解析
      if (!context.getRegistry().containsBeanDefinition(CORS_CONFIGURATION_BEAN_NAME)) {
         RootBeanDefinition corsDef = new RootBeanDefinition(LinkedHashMap.class);
         corsDef.setSource(source);
         corsDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
         if (corsConfigurations != null) {
            corsDef.getConstructorArgumentValues().addIndexedArgumentValue(0, corsConfigurations);
         }
//       註冊mvcCorsConfigurations bean定義
         context.getReaderContext().getRegistry().registerBeanDefinition(CORS_CONFIGURATION_BEAN_NAME, corsDef);
         context.registerComponent(new BeanComponentDefinition(corsDef, CORS_CONFIGURATION_BEAN_NAME));
      }
      else if (corsConfigurations != null) {
         BeanDefinition corsDef = context.getRegistry().getBeanDefinition(CORS_CONFIGURATION_BEAN_NAME);
         corsDef.getConstructorArgumentValues().addIndexedArgumentValue(0, corsConfigurations);
      }
      return new RuntimeBeanReference(CORS_CONFIGURATION_BEAN_NAME);
   }

往上返回到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getValidator

private RuntimeBeanReference getValidator(Element element, Object source, ParserContext context) {
//    解析validator屬性值,註冊驗證服務
      if (element.hasAttribute("validator")) {
         return new RuntimeBeanReference(element.getAttribute("validator"));
      }
      else if (javaxValidationPresent) {
         RootBeanDefinition validatorDef = new RootBeanDefinition(
               "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean");
         validatorDef.setSource(source);
         validatorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
         String validatorName = context.getReaderContext().registerWithGeneratedName(validatorDef);
         context.registerComponent(new BeanComponentDefinition(validatorDef, validatorName));
         return new RuntimeBeanReference(validatorName);
      }
      else {
         return null;
      }
   }

往上返回到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getMessageCodesResolver

private RuntimeBeanReference getMessageCodesResolver(Element element) {
   if (element.hasAttribute("message-codes-resolver")) {
      return new RuntimeBeanReference(element.getAttribute("message-codes-resolver"));
   }
   else {
      return null;
   }
}

往上返回到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getMessageConverters

private ManagedList<?> getMessageConverters(Element element, Object source, ParserContext context) {
      Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");
      ManagedList<Object> messageConverters = new ManagedList<Object>();
      if (convertersElement != null) {
         messageConverters.setSource(source);
         for (Element beanElement : DomUtils.getChildElementsByTagName(convertersElement, "bean", "ref")) {
            Object object = context.getDelegate().parsePropertySubElement(beanElement, null);
            messageConverters.add(object);
         }
      }

//    是否註冊預設值ByteArrayHttpMessageConverter
      if (convertersElement == null || Boolean.valueOf(convertersElement.getAttribute("register-defaults"))) {
         messageConverters.setSource(source);
         messageConverters.add(createConverterDefinition(ByteArrayHttpMessageConverter.class, source));
//       註冊StringHttpMessageConverter bean定義
         RootBeanDefinition stringConverterDef = createConverterDefinition(StringHttpMessageConverter.class, source);
         stringConverterDef.getPropertyValues().add("writeAcceptCharset", false);
         messageConverters.add(stringConverterDef);
//       新增預設轉換器
         messageConverters.add(createConverterDefinition(ResourceHttpMessageConverter.class, source));
         messageConverters.add(createConverterDefinition(SourceHttpMessageConverter.class, source));
//       ->
         messageConverters.add(createConverterDefinition(AllEncompassingFormHttpMessageConverter.class, source));
         if (romePresent) {
            messageConverters.add(createConverterDefinition(AtomFeedHttpMessageConverter.class, source));
            messageConverters.add(createConverterDefinition(RssChannelHttpMessageConverter.class, source));
         }

//       新增json轉xml轉換器
         if (jackson2XmlPresent) {
            Class<?> type = MappingJackson2XmlHttpMessageConverter.class;
            RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
            GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
            jacksonFactoryDef.getPropertyValues().add("createXmlMapper", true);
            jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
            messageConverters.add(jacksonConverterDef);
         }
//       新增物件xml轉換器
         else if (jaxb2Present) {
            messageConverters.add(createConverterDefinition(Jaxb2RootElementHttpMessageConverter.class, source));
         }

//       新增Jackson json轉換器
         if (jackson2Present) {
            Class<?> type = MappingJackson2HttpMessageConverter.class;
            RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
            GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
            jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
            messageConverters.add(jacksonConverterDef);
         }
//       新增Gson json轉換器
         else if (gsonPresent) {
            messageConverters.add(createConverterDefinition(GsonHttpMessageConverter.class, source));
         }
      }
      return messageConverters;
   }

進入到這個方法org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#AllEncompassingFormHttpMessageConverter

public AllEncompassingFormHttpMessageConverter() {
//    新增預設xml和json真支援轉換器
      addPartConverter(new SourceHttpMessageConverter<Source>());
      if (jaxb2Present && !jackson2XmlPresent) {
         addPartConverter(new Jaxb2RootElementHttpMessageConverter());
      }

      if (jackson2Present) {
         addPartConverter(new MappingJackson2HttpMessageConverter());
      }
      else if (gsonPresent) {
         addPartConverter(new GsonHttpMessageConverter());
      }

      if (jackson2XmlPresent) {
         addPartConverter(new MappingJackson2XmlHttpMessageConverter());
      }
   }

往上返回到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getArgumentResolvers

private ManagedList<?> getArgumentResolvers(Element element, ParserContext context) {
      Element resolversElement = DomUtils.getChildElementByTagName(element, "argument-resolvers");
      if (resolversElement != null) {
         ManagedList<Object> resolvers = extractBeanSubElements(resolversElement, context);
//       ->
         return wrapLegacyResolvers(resolvers, context);
      }
      return null;
   }

進入到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#wrapLegacyResolvers

private ManagedList<Object> wrapLegacyResolvers(List<Object> list, ParserContext context) {
      ManagedList<Object> result = new ManagedList<Object>();
      for (Object object : list) {
         if (object instanceof BeanDefinitionHolder) {
            BeanDefinitionHolder beanDef = (BeanDefinitionHolder) object;
            String className = beanDef.getBeanDefinition().getBeanClassName();
            Class<?> clazz = ClassUtils.resolveClassName(className, context.getReaderContext().getBeanClassLoader());
            if (WebArgumentResolver.class.isAssignableFrom(clazz)) {
//             新增ServletWebArgumentResolverAdapter 引數解析器介面卡
               RootBeanDefinition adapter = new RootBeanDefinition(ServletWebArgumentResolverAdapter.class);
               adapter.getConstructorArgumentValues().addIndexedArgumentValue(0, beanDef);
               result.add(new BeanDefinitionHolder(adapter, beanDef.getBeanName() + "Adapter"));
               continue;
            }
         }
         result.add(object);
      }
      return result;
   }

返回到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#parse這一行

//     獲取返回值handler ->
      ManagedList<?> returnValueHandlers = getReturnValueHandlers(element, context);

下次繼續

 

說到最後

本次原始碼解析僅代表個人觀點,僅供參