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

下次继续

 

说到最后

本次源码解析仅代表个人观点,仅供参考。

 

转载于:https://my.oschina.net/u/3775437/blog/3022323

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值