说在前面
前期回顾
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](https://img-blog.csdnimg.cn/img_convert/7c9aabab96d37db286a679787ccaa2dd.gif)
扫码进入技术微信群
![d81d8260e8a2a1b054396c18f465a570.png](https://img-blog.csdnimg.cn/img_convert/d81d8260e8a2a1b054396c18f465a570.png)
![0a82dc83236f67c18c35b8cf5a70bed0.png](https://img-blog.csdnimg.cn/img_convert/0a82dc83236f67c18c35b8cf5a70bed0.png)
![8bc77dac6e7f949a695bd9ef0f4c5b90.png](https://img-blog.csdnimg.cn/img_convert/8bc77dac6e7f949a695bd9ef0f4c5b90.png)
qq技术群