freemarker 解析对象的某元素_springmvc源码架构解析之MvcNamespaceHandler

说在前面

前期回顾

sharding-jdbc源码解析 更新完毕

spring源码解析 更新完毕

spring-mvc源码解析 更新完毕

spring-tx源码解析 更新完毕

spring-boot源码解析 更新完毕

rocketmq源码解析 更新完毕

dubbbo源码解析 更新完毕

netty源码解析 更新完毕

spring源码架构更新完毕

springmvc源码架构更新中

springboot源码架构计划中

github https://github.com/tianheframe

sharding-jdbc源码解析 更新完毕

rocketmq源码解析 更新完毕

seata 源码解析 更新完毕

dubbo 源码解析 更新完毕

netty 源码解析 更新完毕

源码解析

org.springframework.web.servlet.config.MvcNamespaceHandler springmvc的namespaceHandler

@Override  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.beans.factory.xml.NamespaceHandlerSupport类,我们自己实现namespaceHandler也可以继承这个类,注册BeanDefinitionParser,自定义BeanDefinitionParser实现org.springframework.beans.factory.xml.BeanDefinitionParser接口,具体介绍可以查看spring源码架构相关文章。

org.springframework.web.servlet.config.FreeMarkerConfigurerBeanDefinitionParser 解析

@Override    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {//      解析template-loader-path属性值        List childElements = DomUtils.getChildElementsByTagName(element, "template-loader-path");        if (!childElements.isEmpty()) {            List locations = new ArrayList(childElements.size());            for (Element childElement : childElements) {//              解析location属性值                locations.add(childElement.getAttribute("location"));            }            if (locations.isEmpty()) {//              视图文件前缀                locations.add("/WEB-INF/");            }            builder.addPropertyValue("templateLoaderPaths", StringUtils.toStringArray(locations));        }    }

解析beanDefinition

org.springframework.web.servlet.config.DefaultServletHandlerBeanDefinitionParser BeanDefinitionParser,它解析default-servlet-handler元素以注册DefaultServletHttpRequestHandler。还将注册用于映射资源请求的SimpleUrlHandlerMapping和HttpRequestHandlerAdapter。

  @Override  public BeanDefinition parse(Element element, ParserContext parserContext) {    Object source = parserContext.extractSource(element);//    解析default-servlet-name属性值    String defaultServletName = element.getAttribute("default-servlet-name");//    注册DefaultServletHttpRequestHandler bean定义    RootBeanDefinition defaultServletHandlerDef = new RootBeanDefinition(DefaultServletHttpRequestHandler.class);    defaultServletHandlerDef.setSource(source);    defaultServletHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);    if (StringUtils.hasText(defaultServletName)) {      defaultServletHandlerDef.getPropertyValues().add("defaultServletName", defaultServletName);    }    String defaultServletHandlerName = parserContext.getReaderContext().generateBeanName(defaultServletHandlerDef);    parserContext.getRegistry().registerBeanDefinition(defaultServletHandlerName, defaultServletHandlerDef);    parserContext.registerComponent(new BeanComponentDefinition(defaultServletHandlerDef, defaultServletHandlerName));    Map<String, String> urlMap = new ManagedMap<String, String>();//    注册mapping    urlMap.put("/**", defaultServletHandlerName);    RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);    handlerMappingDef.setSource(source);    handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);    handlerMappingDef.getPropertyValues().add("urlMap", urlMap);    String handlerMappingBeanName = parserContext.getReaderContext().generateBeanName(handlerMappingDef);    parserContext.getRegistry().registerBeanDefinition(handlerMappingBeanName, handlerMappingDef);    parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, handlerMappingBeanName));    // Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off" ->    MvcNamespaceUtils.registerDefaultComponents(parserContext, source);    return null;  }

解析BeanDefinition

org.springframework.web.servlet.config.MvcNamespaceUtils#registerDefaultComponents

public static void registerDefaultComponents(ParserContext parserContext, Object source) {//    注册BeanNameUrlHandlerMapping bean定义 ->    registerBeanNameUrlHandlerMapping(parserContext, source);//    注册HttpRequestHandlerAdapter bean定义 ->    registerHttpRequestHandlerAdapter(parserContext, source);//    注册SimpleControllerHandlerAdapter bean定义 ->    registerSimpleControllerHandlerAdapter(parserContext, source);//    注册HandlerMappingIntrospector bean定义 ->    registerHandlerMappingIntrospector(parserContext, source);  }

org.springframework.web.servlet.config.MvcNamespaceUtils#registerBeanNameUrlHandlerMapping

private static void registerBeanNameUrlHandlerMapping(ParserContext context, Object source) {    if (!context.getRegistry().containsBeanDefinition(BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME)){//      注册默认handleMapping组件bean定义      RootBeanDefinition mappingDef = new RootBeanDefinition(BeanNameUrlHandlerMapping.class);      mappingDef.setSource(source);      mappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      mappingDef.getPropertyValues().add("order", 2);  // consistent with WebMvcConfigurationSupport//      注册跨域配置bean定义 ->      RuntimeBeanReference corsRef = MvcNamespaceUtils.registerCorsConfigurations(null, context, source);      mappingDef.getPropertyValues().add("corsConfigurations", corsRef);      context.getRegistry().registerBeanDefinition(BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME, mappingDef);      context.registerComponent(new BeanComponentDefinition(mappingDef, BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME));    }  }

org.springframework.web.servlet.config.MvcNamespaceUtils#registerCorsConfigurations 以已知的名称注册Map (mapping CorsConfigurations),除非已经注册。如果提供了非空CORS配置,则可以更新bean定义。

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.MvcNamespaceUtils#registerHttpRequestHandlerAdapter

private static void registerHttpRequestHandlerAdapter(ParserContext context, Object source) {    if (!context.getRegistry().containsBeanDefinition(HTTP_REQUEST_HANDLER_ADAPTER_BEAN_NAME)) {//      注册默认handlerAdapter组件bean定义      RootBeanDefinition adapterDef = new RootBeanDefinition(HttpRequestHandlerAdapter.class);      adapterDef.setSource(source);      adapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      context.getRegistry().registerBeanDefinition(HTTP_REQUEST_HANDLER_ADAPTER_BEAN_NAME, adapterDef);      context.registerComponent(new BeanComponentDefinition(adapterDef, HTTP_REQUEST_HANDLER_ADAPTER_BEAN_NAME));    }  }

org.springframework.web.servlet.config.MvcNamespaceUtils#registerSimpleControllerHandlerAdapter

  private static void registerSimpleControllerHandlerAdapter(ParserContext context, Object source) {    if (!context.getRegistry().containsBeanDefinition(SIMPLE_CONTROLLER_HANDLER_ADAPTER_BEAN_NAME)) {//      注册默认单一控制器handlerAdapter组件bean定义      RootBeanDefinition beanDef = new RootBeanDefinition(SimpleControllerHandlerAdapter.class);      beanDef.setSource(source);      beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      context.getRegistry().registerBeanDefinition(SIMPLE_CONTROLLER_HANDLER_ADAPTER_BEAN_NAME, beanDef);      context.registerComponent(new BeanComponentDefinition(beanDef, SIMPLE_CONTROLLER_HANDLER_ADAPTER_BEAN_NAME));    }  }

org.springframework.web.servlet.config.MvcNamespaceUtils#registerHandlerMappingIntrospector

private static void registerHandlerMappingIntrospector(ParserContext parserContext, Object source) {    if (!parserContext.getRegistry().containsBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)){//      注册默认内省handlerMapping组件bean定义      RootBeanDefinition beanDef = new RootBeanDefinition(HandlerMappingIntrospector.class);      beanDef.setSource(source);      beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      beanDef.setLazyInit(true);      parserContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, beanDef);      parserContext.registerComponent(new BeanComponentDefinition(beanDef, HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME));    }  }

org.springframework.web.servlet.config.VelocityConfigurerBeanDefinitionParser 解析

@Override  protected void postProcess(BeanDefinitionBuilder builder, Element element) {    if (!builder.getBeanDefinition().hasAttribute("resourceLoaderPath")) {//      默认视图路径      builder.getBeanDefinition().setAttribute("resourceLoaderPath", "/WEB-INF/");    }  }

解析BeanDefinition

org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser 一个BeanDefinitionParser,它为 MVC命名空间元素提供配置。

该类注册以下HandlerMappings:

RequestMappingHandlerMapping按0排序,用于将请求映射到带注释的控制器方法。

BeanNameUrlHandlerMapping按2排序,将URL路径映射到控制器bean名称。

注意:使用或 MVC命名空间元素可能会注册其他HandlerMappings。

该类注册以下handleradapter:

RequestMappingHandlerAdapter用于使用带注释的控制器方法处理请求。

HttpRequestHandlerAdapter,用于使用httprequesthandler处理请求。

SimpleControllerHandlerAdapter用于使用基于接口的控制器处理请求。

这个类注册了以下HandlerExceptionResolvers:

用于通过org.springframe .web.bind.annotation处理异常的ExceptionHandlerExceptionResolver。ExceptionHandler的方法。

ResponseStatusExceptionResolver用于使用org.springframe .web.bind.annotation. responsestatus注释的异常。

DefaultHandlerExceptionResolver,用于解析已知的Spring异常类型

这个类注册了一个org.springframe .util。AntPathMatcher和一个org.springframe .web.util。UrlPathHelper将用于:

RequestMappingHandlerMapping,

视图控制器的HandlerMapping

以及服务资源的HandlerMapping

请注意,可以通过使用路径匹配的MVC名称空间元素来配置这些bean。

RequestMappingHandlerAdapter和ExceptionHandlerExceptionResolver在默认情况下都配置了以下实例:

一个ContentNegotiationManager

一个DefaultFormattingConversionService

org.springframework.validation.beanvalidation。如果类路径上有JSR-303实现,则LocalValidatorFactoryBean

一系列httpmessageconverter,具体取决于类路径上哪些第三方库可用。

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

解析BeanDefinition

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#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 以已知的名称注册Map (mapping CorsConfigurations),除非已经注册。如果提供了非空CORS配置,则可以更新bean定义。

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#getConversionService

private RuntimeBeanReference getConversionService(Element element, Object source, ParserContext context) {    RuntimeBeanReference conversionServiceRef;//    解析conversion-service属性值,注册转换服务    if (element.hasAttribute("conversion-service")) {      conversionServiceRef = new RuntimeBeanReference(element.getAttribute("conversion-service"));    }    else {//      如果没有配置conversion-service,默认注册FormattingConversionServiceFactoryBean ->      RootBeanDefinition conversionDef = new RootBeanDefinition(FormattingConversionServiceFactoryBean.class);      conversionDef.setSource(source);      conversionDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      String conversionName = context.getReaderContext().registerWithGeneratedName(conversionDef);      context.registerComponent(new BeanComponentDefinition(conversionDef, conversionName));      conversionServiceRef = new RuntimeBeanReference(conversionName);    }    return conversionServiceRef;  }

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 messageConverters = new ManagedList();    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.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getArgumentResolvers

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

org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#wrapLegacyResolvers

private ManagedList wrapLegacyResolvers(List list, ParserContext context) {    ManagedList result = new ManagedList();    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#getReturnValueHandlers

  private ManagedList> getMessageConverters(Element element, Object source, ParserContext context) {    Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");    ManagedList messageConverters = new ManagedList();    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.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getAsyncTimeout

private String getAsyncTimeout(Element element) {    Element asyncElement = DomUtils.getChildElementByTagName(element, "async-support");    return (asyncElement != null ? asyncElement.getAttribute("default-timeout") : null);  }

org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getAsyncExecutor

private RuntimeBeanReference getAsyncExecutor(Element element) {//    注册异步执行器    Element asyncElement = DomUtils.getChildElementByTagName(element, "async-support");    if (asyncElement != null && asyncElement.hasAttribute("task-executor")) {      return new RuntimeBeanReference(asyncElement.getAttribute("task-executor"));    }    return null;  }

org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getCallableInterceptors

private ManagedList> getCallableInterceptors(Element element, Object source, ParserContext context) {    ManagedList<Object> interceptors = new ManagedList<Object>();    Element asyncElement = DomUtils.getChildElementByTagName(element, "async-support");    if (asyncElement != null) {//      注册异步支持回调拦截器      Element interceptorsElement = DomUtils.getChildElementByTagName(asyncElement, "callable-interceptors");      if (interceptorsElement != null) {        interceptors.setSource(source);        for (Element converter : DomUtils.getChildElementsByTagName(interceptorsElement, "bean")) {          BeanDefinitionHolder beanDef = context.getDelegate().parseBeanDefinitionElement(converter);          beanDef = context.getDelegate().decorateBeanDefinitionIfRequired(converter, beanDef);          interceptors.add(beanDef);        }      }    }    return interceptors;  }

org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getDeferredResultInterceptors

private ManagedList> getDeferredResultInterceptors(Element element, Object source, ParserContext context) {    ManagedList<Object> interceptors = new ManagedList<Object>();    Element asyncElement = DomUtils.getChildElementByTagName(element, "async-support");    if (asyncElement != null) {//      注册默认延迟结果拦截器      Element interceptorsElement = DomUtils.getChildElementByTagName(asyncElement, "deferred-result-interceptors");      if (interceptorsElement != null) {        interceptors.setSource(source);        for (Element converter : DomUtils.getChildElementsByTagName(interceptorsElement, "bean")) {          BeanDefinitionHolder beanDef = context.getDelegate().parseBeanDefinitionElement(converter);          beanDef = context.getDelegate().decorateBeanDefinitionIfRequired(converter, beanDef);          interceptors.add(beanDef);        }      }    }    return interceptors;  }

org.springframework.web.servlet.config.MvcNamespaceUtils#registerDefaultComponents

  public static void registerDefaultComponents(ParserContext parserContext, Object source) {//    注册BeanNameUrlHandlerMapping bean定义 ->    registerBeanNameUrlHandlerMapping(parserContext, source);//    注册HttpRequestHandlerAdapter bean定义 ->    registerHttpRequestHandlerAdapter(parserContext, source);//    注册SimpleControllerHandlerAdapter bean定义 ->    registerSimpleControllerHandlerAdapter(parserContext, source);//    注册HandlerMappingIntrospector bean定义 ->    registerHandlerMappingIntrospector(parserContext, source);  }

org.springframework.web.servlet.config.MvcNamespaceUtils#registerBeanNameUrlHandlerMapping

private static void registerBeanNameUrlHandlerMapping(ParserContext context, Object source) {    if (!context.getRegistry().containsBeanDefinition(BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME)){//      注册默认handleMapping组件bean定义      RootBeanDefinition mappingDef = new RootBeanDefinition(BeanNameUrlHandlerMapping.class);      mappingDef.setSource(source);      mappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      mappingDef.getPropertyValues().add("order", 2);  // consistent with WebMvcConfigurationSupport//      注册跨域配置bean定义 ->      RuntimeBeanReference corsRef = MvcNamespaceUtils.registerCorsConfigurations(null, context, source);      mappingDef.getPropertyValues().add("corsConfigurations", corsRef);      context.getRegistry().registerBeanDefinition(BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME, mappingDef);      context.registerComponent(new BeanComponentDefinition(mappingDef, BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME));    }  }

org.springframework.web.servlet.config.MvcNamespaceUtils#registerCorsConfigurations 以已知的名称注册Map (mapping CorsConfigurations),除非已经注册。如果提供了非空CORS配置,则可以更新bean定义。

  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.MvcNamespaceUtils#registerHttpRequestHandlerAdapter

  private static void registerHttpRequestHandlerAdapter(ParserContext context, Object source) {    if (!context.getRegistry().containsBeanDefinition(HTTP_REQUEST_HANDLER_ADAPTER_BEAN_NAME)) {//      注册默认handlerAdapter组件bean定义      RootBeanDefinition adapterDef = new RootBeanDefinition(HttpRequestHandlerAdapter.class);      adapterDef.setSource(source);      adapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      context.getRegistry().registerBeanDefinition(HTTP_REQUEST_HANDLER_ADAPTER_BEAN_NAME, adapterDef);      context.registerComponent(new BeanComponentDefinition(adapterDef, HTTP_REQUEST_HANDLER_ADAPTER_BEAN_NAME));    }  }

org.springframework.web.servlet.config.MvcNamespaceUtils#registerSimpleControllerHandlerAdapter

private static void registerSimpleControllerHandlerAdapter(ParserContext context, Object source) {    if (!context.getRegistry().containsBeanDefinition(SIMPLE_CONTROLLER_HANDLER_ADAPTER_BEAN_NAME)) {//      注册默认单一控制器handlerAdapter组件bean定义      RootBeanDefinition beanDef = new RootBeanDefinition(SimpleControllerHandlerAdapter.class);      beanDef.setSource(source);      beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      context.getRegistry().registerBeanDefinition(SIMPLE_CONTROLLER_HANDLER_ADAPTER_BEAN_NAME, beanDef);      context.registerComponent(new BeanComponentDefinition(beanDef, SIMPLE_CONTROLLER_HANDLER_ADAPTER_BEAN_NAME));    }  }

org.springframework.web.servlet.config.MvcNamespaceUtils#registerHandlerMappingIntrospector

private static void registerHandlerMappingIntrospector(ParserContext parserContext, Object source) {    if (!parserContext.getRegistry().containsBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)){//      注册默认内省handlerMapping组件bean定义      RootBeanDefinition beanDef = new RootBeanDefinition(HandlerMappingIntrospector.class);      beanDef.setSource(source);      beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      beanDef.setLazyInit(true);      parserContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, beanDef);      parserContext.registerComponent(new BeanComponentDefinition(beanDef, HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME));    }  }

org.springframework.web.servlet.config.ViewControllerBeanDefinitionParser 所有元素都会导致ParameterizableViewController的注册,该视图控制器使用单个SimpleUrlHandlerMapping中的所有控制器进行映射。

  @Override  @SuppressWarnings("unchecked")  public BeanDefinition parse(Element element, ParserContext parserContext) {    Object source = parserContext.extractSource(element);    // Register SimpleUrlHandlerMapping for view controllers 注册viewControllerHandlerMapping bean定义 ->    BeanDefinition hm = registerHandlerMapping(parserContext, source);    // Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off" 注册默认组件 ->    MvcNamespaceUtils.registerDefaultComponents(parserContext, source);    // Create view controller bean definition 注册ParameterizableViewController bean定义    RootBeanDefinition controller = new RootBeanDefinition(ParameterizableViewController.class);    controller.setSource(source);    HttpStatus statusCode = null;//    解析状态吗    if (element.hasAttribute("status-code")) {      int statusValue = Integer.parseInt(element.getAttribute("status-code"));      statusCode = HttpStatus.valueOf(statusValue);    }    String name = element.getLocalName();//    解析view-controller属性值,不经过controller直接转发访问视图    if (name.equals("view-controller")) {      if (element.hasAttribute("view-name")) {        controller.getPropertyValues().add("viewName", element.getAttribute("view-name"));      }      if (statusCode != null) {        controller.getPropertyValues().add("statusCode", statusCode);      }    }//    解析view-controller属性值,不经过controller直接重定向访问视图    else if (name.equals("redirect-view-controller")) {//      解析重定向视图  ->      controller.getPropertyValues().add("view", getRedirectView(element, statusCode, source));    }//    解析status-controller属性值,不经过controller直接返回状态码    else if (name.equals("status-controller")) {      controller.getPropertyValues().add("statusCode", statusCode);      controller.getPropertyValues().add("statusOnly", true);    }    else {      // Should never happen...      throw new IllegalStateException("Unexpected tag name: " + name);    }    Map urlMap;    if (hm.getPropertyValues().contains("urlMap")) {      urlMap = (Map) hm.getPropertyValues().getPropertyValue("urlMap").getValue();    }    else {      urlMap = new ManagedMap();      hm.getPropertyValues().add("urlMap", urlMap);    }    urlMap.put(element.getAttribute("path"), controller);    return null;  }

解析BeanDefinition

org.springframework.web.servlet.config.ViewControllerBeanDefinitionParser#registerHandlerMapping 注册handlerMapping BeanDefinition

private BeanDefinition registerHandlerMapping(ParserContext context, Object source) {//    是否已注册viewControllerHandlerMapping bean定义    if (context.getRegistry().containsBeanDefinition(HANDLER_MAPPING_BEAN_NAME)) {      return context.getRegistry().getBeanDefinition(HANDLER_MAPPING_BEAN_NAME);    }//    注册SimpleUrlHandlerMapping bean定义    RootBeanDefinition beanDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);    beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);    context.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, beanDef);    context.registerComponent(new BeanComponentDefinition(beanDef, HANDLER_MAPPING_BEAN_NAME));    beanDef.setSource(source);    beanDef.getPropertyValues().add("order", "1");//    注册路径匹配器 ->    beanDef.getPropertyValues().add("pathMatcher", MvcNamespaceUtils.registerPathMatcher(null, context, source));//    注册url路径匹配器 ->    beanDef.getPropertyValues().add("urlPathHelper", MvcNamespaceUtils.registerUrlPathHelper(null, context, source));//    注册跨域配置 ->    RuntimeBeanReference corsConfigurationsRef = MvcNamespaceUtils.registerCorsConfigurations(null, context, source);    beanDef.getPropertyValues().add("corsConfigurations", corsConfigurationsRef);    return beanDef;  }

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#registerUrlPathHelper 向现有的已知名称添加别名,或以该已知名称注册UrlPathHelper的新实例,除非已经注册。

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#registerCorsConfigurations 以已知的名称注册Map (mapping CorsConfigurations),除非已经注册。如果提供了非空CORS配置,则可以更新bean定义。

  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.MvcNamespaceUtils#registerDefaultComponents

  public static void registerDefaultComponents(ParserContext parserContext, Object source) {//    注册BeanNameUrlHandlerMapping bean定义 ->    registerBeanNameUrlHandlerMapping(parserContext, source);//    注册HttpRequestHandlerAdapter bean定义 ->    registerHttpRequestHandlerAdapter(parserContext, source);//    注册SimpleControllerHandlerAdapter bean定义 ->    registerSimpleControllerHandlerAdapter(parserContext, source);//    注册HandlerMappingIntrospector bean定义 ->    registerHandlerMappingIntrospector(parserContext, source);  }

org.springframework.web.servlet.config.ViewControllerBeanDefinitionParser#getRedirectView

private RootBeanDefinition getRedirectView(Element element, HttpStatus status, Object source) {//    解析RedirectView bean定义    RootBeanDefinition redirectView = new RootBeanDefinition(RedirectView.class);    redirectView.setSource(source);//    解析重定向路径    redirectView.getConstructorArgumentValues().addIndexedArgumentValue(0, element.getAttribute("redirect-url"));    if (status != null) {      redirectView.getPropertyValues().add("statusCode", status);    }//    是否上下文相对路径    if (element.hasAttribute("context-relative")) {      redirectView.getPropertyValues().add("contextRelative", element.getAttribute("context-relative"));    }    else {      redirectView.getPropertyValues().add("contextRelative", true);    }//    传递查询参数    if (element.hasAttribute("keep-query-params")) {      redirectView.getPropertyValues().add("propagateQueryParams", element.getAttribute("keep-query-params"));    }    return redirectView;  }

org.springframework.web.servlet.config.ViewResolversBeanDefinitionParser 解析视图解析器MVC名称空间元素并注册org.springframe .web.servlet。ViewResolver bean定义。所有注册的解析器都包装在一个单独(复合)的视图解析器中,其order属性设置为0,以便其他外部解析器可以在它之前或之后进行排序。当启用内容协商时,order属性被设置为最高优先级,而contentnegotiation ingviewresolver则封装所有其他注册的视图解析器实例。这样,通过MVC命名空间注册的解析器就形成了自封装的解析器链。

public BeanDefinition parse(Element element, ParserContext context) {    Object source = context.extractSource(element);    context.pushContainingComponent(new CompositeComponentDefinition(element.getTagName(), source));    ManagedList resolvers = new ManagedList(4);    resolvers.setSource(context.extractSource(element));//    支持以下视图    String[] names = new String[] {"jsp", "tiles", "bean-name", "freemarker", "velocity", "groovy", "script-template", "bean", "ref"};    for (Element resolverElement : DomUtils.getChildElementsByTagName(element, names)) {      String name = resolverElement.getLocalName();      if ("bean".equals(name) || "ref".equals(name)) {        resolvers.add(context.getDelegate().parsePropertySubElement(resolverElement, null));        continue;      }      RootBeanDefinition resolverBeanDef;      if ("jsp".equals(name)) {//        注册InternalResourceViewResolver视图解析器bean定义        resolverBeanDef = new RootBeanDefinition(InternalResourceViewResolver.class);//        视图文件前缀        resolverBeanDef.getPropertyValues().add("prefix", "/WEB-INF/");//        视图文件后缀        resolverBeanDef.getPropertyValues().add("suffix", ".jsp");//        添加基于url的视图属性 ->        addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);      }      else if ("tiles".equals(name)) {        resolverBeanDef = new RootBeanDefinition(TilesViewResolver.class);        addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);      }      else if ("freemarker".equals(name)) {//        解析FreeMarkerViewResolver bean定义        resolverBeanDef = new RootBeanDefinition(FreeMarkerViewResolver.class);        resolverBeanDef.getPropertyValues().add("suffix", ".ftl");        addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);      }      else if ("velocity".equals(name)) {//        解析VelocityViewResolver bean定义        resolverBeanDef = new RootBeanDefinition(org.springframework.web.servlet.view.velocity.VelocityViewResolver.class);        resolverBeanDef.getPropertyValues().add("suffix", ".vm");        addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);      }      else if ("groovy".equals(name)) {        resolverBeanDef = new RootBeanDefinition(GroovyMarkupViewResolver.class);        resolverBeanDef.getPropertyValues().add("suffix", ".tpl");        addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);      }      else if ("script-template".equals(name)) {        resolverBeanDef = new RootBeanDefinition(ScriptTemplateViewResolver.class);        addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);      }      else if ("bean-name".equals(name)) {//        解析BeanNameViewResolver bean定义        resolverBeanDef = new RootBeanDefinition(BeanNameViewResolver.class);      }      else {        // Should never happen        throw new IllegalStateException("Unexpected element name: " + name);      }      resolverBeanDef.setSource(source);      resolverBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      resolvers.add(resolverBeanDef);    }    String beanName = VIEW_RESOLVER_BEAN_NAME;//    解析ViewResolverComposite bean定义    RootBeanDefinition compositeResolverBeanDef = new RootBeanDefinition(ViewResolverComposite.class);    compositeResolverBeanDef.setSource(source);    compositeResolverBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);    names = new String[] {"content-negotiation"};    List contentNegotiationElements = DomUtils.getChildElementsByTagName(element, names);    if (contentNegotiationElements.isEmpty()) {      compositeResolverBeanDef.getPropertyValues().add("viewResolvers", resolvers);    }    else if (contentNegotiationElements.size() == 1) {//      创建媒体类型视图解析器 ->      BeanDefinition beanDef = createContentNegotiatingViewResolver(contentNegotiationElements.get(0), context);//      组合视图解析器,解析viewResolvers属性值      beanDef.getPropertyValues().add("viewResolvers", resolvers);      ManagedList list = new ManagedList(1);      list.add(beanDef);//      视图解析器的使用顺序      compositeResolverBeanDef.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);      compositeResolverBeanDef.getPropertyValues().add("viewResolvers", list);    }    else {      throw new IllegalArgumentException("Only one  element is allowed.");    }    if (element.hasAttribute("order")) {      compositeResolverBeanDef.getPropertyValues().add("order", element.getAttribute("order"));    }//    注册mvcViewResolver bean定义    context.getReaderContext().getRegistry().registerBeanDefinition(beanName, compositeResolverBeanDef);    context.registerComponent(new BeanComponentDefinition(compositeResolverBeanDef, beanName));    context.popAndRegisterContainingComponent();    return null;  }

解析BeanDefinition

org.springframework.web.servlet.config.ViewResolversBeanDefinitionParser#addUrlBasedViewResolverProperties

private void addUrlBasedViewResolverProperties(Element element, RootBeanDefinition beanDefinition) {    if (element.hasAttribute("prefix")) {      beanDefinition.getPropertyValues().add("prefix", element.getAttribute("prefix"));    }    if (element.hasAttribute("suffix")) {      beanDefinition.getPropertyValues().add("suffix", element.getAttribute("suffix"));    }    if (element.hasAttribute("cache-views")) {      beanDefinition.getPropertyValues().add("cache", element.getAttribute("cache-views"));    }    if (element.hasAttribute("view-class")) {      beanDefinition.getPropertyValues().add("viewClass", element.getAttribute("view-class"));    }    if (element.hasAttribute("view-names")) {      beanDefinition.getPropertyValues().add("viewNames", element.getAttribute("view-names"));    }  }

org.springframework.web.servlet.config.ViewResolversBeanDefinitionParser#createContentNegotiatingViewResolver

  private BeanDefinition createContentNegotiatingViewResolver(Element resolverElement, ParserContext context) {//    注册ContentNegotiatingViewResolver bean定义    RootBeanDefinition beanDef = new RootBeanDefinition(ContentNegotiatingViewResolver.class);    beanDef.setSource(context.extractSource(resolverElement));    beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);    MutablePropertyValues values = beanDef.getPropertyValues();//    默认视图    List elements = DomUtils.getChildElementsByTagName(resolverElement, "default-views");    if (!elements.isEmpty()) {      ManagedList list = new ManagedList();      for (Element element : DomUtils.getChildElementsByTagName(elements.get(0), "bean", "ref")) {        list.add(context.getDelegate().parsePropertySubElement(element, null));      }      values.add("defaultViews", list);    }//    是否开启不接受设置    if (resolverElement.hasAttribute("use-not-acceptable")) {      values.add("useNotAcceptableStatusCode", resolverElement.getAttribute("use-not-acceptable"));    }//    获取媒体类型管理器bean定义 ->    Object manager = MvcNamespaceUtils.getContentNegotiationManager(context);    if (manager != null) {      values.add("contentNegotiationManager", manager);    }    return beanDef;  }

org.springframework.web.servlet.config.InterceptorsBeanDefinitionParser 

@Override  public BeanDefinition parse(Element element, ParserContext parserContext) {    CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));    parserContext.pushContainingComponent(compDefinition);    RuntimeBeanReference pathMatcherRef = null;//    解析路径适配器    if (element.hasAttribute("path-matcher")) {      pathMatcherRef = new RuntimeBeanReference(element.getAttribute("path-matcher"));    }    List interceptors = DomUtils.getChildElementsByTagName(element, "bean", "ref", "interceptor");    for (Element interceptor : interceptors) {      RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);      mappedInterceptorDef.setSource(parserContext.extractSource(interceptor));      mappedInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      ManagedList<String> includePatterns = null;      ManagedList<String> excludePatterns = null;      Object interceptorBean;//      注册拦截器bean定义      if ("interceptor".equals(interceptor.getLocalName())) {//        包含路径的适配器 ->        includePatterns = getIncludePatterns(interceptor, "mapping");//        包含路径的映射路径 ->        excludePatterns = getIncludePatterns(interceptor, "exclude-mapping");        Element beanElem = DomUtils.getChildElementsByTagName(interceptor, "bean", "ref").get(0);        interceptorBean = parserContext.getDelegate().parsePropertySubElement(beanElem, null);      }      else {        interceptorBean = parserContext.getDelegate().parsePropertySubElement(interceptor, null);      }      mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, includePatterns);      mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, excludePatterns);      mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, interceptorBean);      if (pathMatcherRef != null) {        mappedInterceptorDef.getPropertyValues().add("pathMatcher", pathMatcherRef);      }      String beanName = parserContext.getReaderContext().registerWithGeneratedName(mappedInterceptorDef);      parserContext.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, beanName));    }    parserContext.popAndRegisterContainingComponent();    return null;  }

解析BeanDefinition

org.springframework.web.servlet.config.InterceptorsBeanDefinitionParser#getIncludePatterns

private ManagedList<String> getIncludePatterns(Element interceptor, String elementName) {    List paths = DomUtils.getChildElementsByTagName(interceptor, elementName);    ManagedList<String> patterns = new ManagedList<String>(paths.size());    for (Element path : paths) {      patterns.add(path.getAttribute("path"));//      解析path属性值    }    return patterns;  }

org.springframework.web.servlet.config.ResourcesBeanDefinitionParser BeanDefinitionParser,它解析资源元素以注册ResourceHttpRequestHandler和注册SimpleUrlHandlerMapping以映射资源请求,以及HttpRequestHandlerAdapter。还将使用ResourceResolvers和resourcetransformer创建一个资源处理链。

@Override  public BeanDefinition parse(Element element, ParserContext context) {    Object source = context.extractSource(element);//    注册url服务处理器 ->    registerUrlProvider(context, source);//    注册路径匹配器bean定义 ->    RuntimeBeanReference pathMatcherRef = MvcNamespaceUtils.registerPathMatcher(null, context, source);//    注册url路径匹配器bean定义 ->    RuntimeBeanReference pathHelperRef = MvcNamespaceUtils.registerUrlPathHelper(null, context, source);//    注册resourceHandler ->    String resourceHandlerName = registerResourceHandler(context, element, pathHelperRef, source);    if (resourceHandlerName == null) {      return null;    }    Map<String, String> urlMap = new ManagedMap<String, String>();//    解析映射    String resourceRequestPath = element.getAttribute("mapping");    if (!StringUtils.hasText(resourceRequestPath)) {      context.getReaderContext().error("The 'mapping' attribute is required.", context.extractSource(element));      return null;    }    urlMap.put(resourceRequestPath, resourceHandlerName);//    注册SimpleUrlHandlerMapping bean定义    RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);    handlerMappingDef.setSource(source);    handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);    handlerMappingDef.getPropertyValues().add("urlMap", urlMap);    handlerMappingDef.getPropertyValues().add("pathMatcher", pathMatcherRef).add("urlPathHelper", pathHelperRef);//    解析顺序属性    String orderValue = element.getAttribute("order");    // Use a default of near-lowest precedence, still allowing for even lower precedence in other mappings    Object order = StringUtils.hasText(orderValue) ? orderValue : Ordered.LOWEST_PRECEDENCE - 1;    handlerMappingDef.getPropertyValues().add("order", order);//    注册跨域bean支持bean定义 ->    RuntimeBeanReference corsRef = MvcNamespaceUtils.registerCorsConfigurations(null, context, source);    handlerMappingDef.getPropertyValues().add("corsConfigurations", corsRef);    String beanName = context.getReaderContext().generateBeanName(handlerMappingDef);    context.getRegistry().registerBeanDefinition(beanName, handlerMappingDef);    context.registerComponent(new BeanComponentDefinition(handlerMappingDef, beanName));    // Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off"    // Register HttpRequestHandlerAdapter 注册默认组件 ->    MvcNamespaceUtils.registerDefaultComponents(context, source);    return null;  }

解析BeanDefinition

org.springframework.web.servlet.config.ResourcesBeanDefinitionParser#registerUrlProvider

private void registerUrlProvider(ParserContext context, Object source) {    if (!context.getRegistry().containsBeanDefinition(RESOURCE_URL_PROVIDER)) {      RootBeanDefinition urlProvider = new RootBeanDefinition(ResourceUrlProvider.class);      urlProvider.setSource(source);      urlProvider.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      context.getRegistry().registerBeanDefinition(RESOURCE_URL_PROVIDER, urlProvider);//      注册mvcResourceUrlProvider bean定义      context.registerComponent(new BeanComponentDefinition(urlProvider, RESOURCE_URL_PROVIDER));//      注册ResourceUrlProviderExposingInterceptor bean定义      RootBeanDefinition interceptor = new RootBeanDefinition(ResourceUrlProviderExposingInterceptor.class);      interceptor.setSource(source);      interceptor.getConstructorArgumentValues().addIndexedArgumentValue(0, urlProvider);//      注册MappedInterceptor bean定义      RootBeanDefinition mappedInterceptor = new RootBeanDefinition(MappedInterceptor.class);      mappedInterceptor.setSource(source);      mappedInterceptor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      mappedInterceptor.getConstructorArgumentValues().addIndexedArgumentValue(0, (Object) null);      mappedInterceptor.getConstructorArgumentValues().addIndexedArgumentValue(1, interceptor);      String mappedInterceptorName = context.getReaderContext().registerWithGeneratedName(mappedInterceptor);      context.registerComponent(new BeanComponentDefinition(mappedInterceptor, mappedInterceptorName));    }  }

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#registerUrlPathHelper 向现有的已知名称添加别名,或以该已知名称注册UrlPathHelper的新实例,除非已经注册。

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.ResourcesBeanDefinitionParser#registerResourceHandler 

  private String registerResourceHandler(      ParserContext context, Element element, RuntimeBeanReference pathHelperRef, Object source) {//    解析location属性值    String locationAttr = element.getAttribute("location");    if (!StringUtils.hasText(locationAttr)) {      context.getReaderContext().error("The 'location' attribute is required.", context.extractSource(element));      return null;    }//    注册ResourceHttpRequestHandler bean定义    RootBeanDefinition resourceHandlerDef = new RootBeanDefinition(ResourceHttpRequestHandler.class);    resourceHandlerDef.setSource(source);    resourceHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);    MutablePropertyValues values = resourceHandlerDef.getPropertyValues();//    解析url路径解析器    values.add("urlPathHelper", pathHelperRef);//    解析路径值    values.add("locationValues", StringUtils.commaDelimitedListToStringArray(locationAttr));//    获取缓存周期    String cacheSeconds = element.getAttribute("cache-period");    if (StringUtils.hasText(cacheSeconds)) {      values.add("cacheSeconds", cacheSeconds);    }//    获取缓存配置    Element cacheControlElement = DomUtils.getChildElementByTagName(element, "cache-control");    if (cacheControlElement != null) {//      解析缓存配置 ->      CacheControl cacheControl = parseCacheControl(cacheControlElement);      values.add("cacheControl", cacheControl);    }//    获取资源域属性    Element resourceChainElement = DomUtils.getChildElementByTagName(element, "resource-chain");    if (resourceChainElement != null) {//      解析资源域 ->      parseResourceChain(resourceHandlerDef, context, resourceChainElement, source);    }//    获取媒体类型管理器 ->    Object manager = MvcNamespaceUtils.getContentNegotiationManager(context);    if (manager != null) {      values.add("contentNegotiationManager", manager);    }    String beanName = context.getReaderContext().generateBeanName(resourceHandlerDef);    context.getRegistry().registerBeanDefinition(beanName, resourceHandlerDef);    context.registerComponent(new BeanComponentDefinition(resourceHandlerDef, beanName));    return beanName;  }

org.springframework.web.servlet.config.ResourcesBeanDefinitionParser#parseCacheControl

private CacheControl parseCacheControl(Element element) {    CacheControl cacheControl;    if ("true".equals(element.getAttribute("no-cache"))) {      cacheControl = CacheControl.noCache();    }    else if ("true".equals(element.getAttribute("no-store"))) {      cacheControl = CacheControl.noStore();    }    else if (element.hasAttribute("max-age")) {      cacheControl = CacheControl.maxAge(Long.parseLong(element.getAttribute("max-age")), TimeUnit.SECONDS);    }    else {      cacheControl = CacheControl.empty();    }    if ("true".equals(element.getAttribute("must-revalidate"))) {      cacheControl = cacheControl.mustRevalidate();    }    if ("true".equals(element.getAttribute("no-transform"))) {      cacheControl = cacheControl.noTransform();    }    if ("true".equals(element.getAttribute("cache-public"))) {      cacheControl = cacheControl.cachePublic();    }    if ("true".equals(element.getAttribute("cache-private"))) {      cacheControl = cacheControl.cachePrivate();    }    if ("true".equals(element.getAttribute("proxy-revalidate"))) {      cacheControl = cacheControl.proxyRevalidate();    }    if (element.hasAttribute("s-maxage")) {      cacheControl = cacheControl.sMaxAge(Long.parseLong(element.getAttribute("s-maxage")), TimeUnit.SECONDS);    }    if (element.hasAttribute("stale-while-revalidate")) {      cacheControl = cacheControl.staleWhileRevalidate(          Long.parseLong(element.getAttribute("stale-while-revalidate")), TimeUnit.SECONDS);    }    if (element.hasAttribute("stale-if-error")) {      cacheControl = cacheControl.staleIfError(          Long.parseLong(element.getAttribute("stale-if-error")), TimeUnit.SECONDS);    }    return cacheControl;  }

org.springframework.web.servlet.config.ResourcesBeanDefinitionParser#parseResourceChain

  private void parseResourceChain(      RootBeanDefinition resourceHandlerDef, ParserContext context, Element element, Object source) {    String autoRegistration = element.getAttribute("auto-registration");    boolean isAutoRegistration = !(StringUtils.hasText(autoRegistration) && "false".equals(autoRegistration));    ManagedList<Object> resourceResolvers = new ManagedList<Object>();    resourceResolvers.setSource(source);    ManagedList<Object> resourceTransformers = new ManagedList<Object>();    resourceTransformers.setSource(source);//    解析资源缓存 ->    parseResourceCache(resourceResolvers, resourceTransformers, element, source);//    解析资源解析转换器    parseResourceResolversTransformers(        isAutoRegistration, resourceResolvers, resourceTransformers, context, element, source);    if (!resourceResolvers.isEmpty()) {      resourceHandlerDef.getPropertyValues().add("resourceResolvers", resourceResolvers);    }    if (!resourceTransformers.isEmpty()) {      resourceHandlerDef.getPropertyValues().add("resourceTransformers", resourceTransformers);    }  }

org.springframework.web.servlet.config.MvcNamespaceUtils#getContentNegotiationManager

public static Object getContentNegotiationManager(ParserContext context) {    String name = AnnotationDrivenBeanDefinitionParser.HANDLER_MAPPING_BEAN_NAME;    if (context.getRegistry().containsBeanDefinition(name)) {      BeanDefinition handlerMappingBeanDef = context.getRegistry().getBeanDefinition(name);//      从RequestMappingHandlerMapping bean定义中获取      return handlerMappingBeanDef.getPropertyValues().get("contentNegotiationManager");    }    name = AnnotationDrivenBeanDefinitionParser.CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;    if (context.getRegistry().containsBeanDefinition(name)) {      return new RuntimeBeanReference(name);    }    return null;  }

org.springframework.web.servlet.config.MvcNamespaceUtils#registerCorsConfigurations 以已知的名称注册Map (mapping CorsConfigurations),除非已经注册。如果提供了非空CORS配置,则可以更新bean定义。

  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.MvcNamespaceUtils#registerDefaultComponents

public static void registerDefaultComponents(ParserContext parserContext, Object source) {//    注册BeanNameUrlHandlerMapping bean定义 ->    registerBeanNameUrlHandlerMapping(parserContext, source);//    注册HttpRequestHandlerAdapter bean定义 ->    registerHttpRequestHandlerAdapter(parserContext, source);//    注册SimpleControllerHandlerAdapter bean定义 ->    registerSimpleControllerHandlerAdapter(parserContext, source);//    注册HandlerMappingIntrospector bean定义 ->    registerHandlerMappingIntrospector(parserContext, source);  }

org.springframework.web.servlet.config.CorsBeanDefinitionParser BeanDefinitionParser,它解析cors元素,以便在由AnnotationDrivenBeanDefinitionParser、ResourcesBeanDefinitionParser和ViewControllerBeanDefinitionParser创建的各种{AbstractHandlerMapping} bean中设置cors配置。

@Override  public BeanDefinition parse(Element element, ParserContext parserContext) {    Map<String, CorsConfiguration> corsConfigurations = new LinkedHashMap<String, CorsConfiguration>();//    解析映射    List mappings = DomUtils.getChildElementsByTagName(element, "mapping");    if (mappings.isEmpty()) {//      添加允许的默认值 ->      CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues();//      如果是空,所有路径都支持跨域      corsConfigurations.put("/**", config);    }    else {      for (Element mapping : mappings) {        CorsConfiguration config = new CorsConfiguration();//        允许跨的域        if (mapping.hasAttribute("allowed-origins")) {          String[] allowedOrigins = StringUtils.tokenizeToStringArray(mapping.getAttribute("allowed-origins"), ",");          config.setAllowedOrigins(Arrays.asList(allowedOrigins));        }//        允许跨域的方法        if (mapping.hasAttribute("allowed-methods")) {          String[] allowedMethods = StringUtils.tokenizeToStringArray(mapping.getAttribute("allowed-methods"), ",");          config.setAllowedMethods(Arrays.asList(allowedMethods));        }//        允许跨域的headers        if (mapping.hasAttribute("allowed-headers")) {          String[] allowedHeaders = StringUtils.tokenizeToStringArray(mapping.getAttribute("allowed-headers"), ",");          config.setAllowedHeaders(Arrays.asList(allowedHeaders));        }//        暴露的headers        if (mapping.hasAttribute("exposed-headers")) {          String[] exposedHeaders = StringUtils.tokenizeToStringArray(mapping.getAttribute("exposed-headers"), ",");          config.setExposedHeaders(Arrays.asList(exposedHeaders));        }//        允许的凭证        if (mapping.hasAttribute("allow-credentials")) {          config.setAllowCredentials(Boolean.parseBoolean(mapping.getAttribute("allow-credentials")));        }        if (mapping.hasAttribute("max-age")) {          config.setMaxAge(Long.parseLong(mapping.getAttribute("max-age")));        }        corsConfigurations.put(mapping.getAttribute("path"), config.applyPermitDefaultValues());      }    }//    注册跨域配置 ->    MvcNamespaceUtils.registerCorsConfigurations(corsConfigurations, parserContext, parserContext.extractSource(element));    return null;  }

org.springframework.web.servlet.config.MvcNamespaceUtils#registerCorsConfigurations 以已知的名称注册Map (mapping CorsConfigurations),除非已经注册。如果提供了非空CORS配置,则可以更新bean定义。

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

说在最后

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

7c9aabab96d37db286a679787ccaa2dd.gif

扫码进入技术微信群

d81d8260e8a2a1b054396c18f465a570.png 0a82dc83236f67c18c35b8cf5a70bed0.png 8bc77dac6e7f949a695bd9ef0f4c5b90.png钉钉技术群

7d85890d5091f2b01b1ec74e60299ee1.png

qq技术群

ad328b47fc7aae1cb6d3b199692cef89.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值