说在前面
本次主要介绍springmvc配置解析<mvc:freemarker-configurer/>、<mvc:velocity-configurer/>、 <mvc:cors>。关注“天河聊技术”更多中间件源码解析。
springmvc配置解析
本次介绍MvcNamespaceHandler。
进入到这个方法org.springframework.web.servlet.config.FreeMarkerConfigurerBeanDefinitionParser#doParse
@Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { // 解析template-loader-path属性值 List<Element> childElements = DomUtils.getChildElementsByTagName(element, "template-loader-path"); if (!childElements.isEmpty()) { List<String> locations = new ArrayList<String>(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)); } }
进入到这个方法org.springframework.web.servlet.config.VelocityConfigurerBeanDefinitionParser#postProcess
@Override protected void postProcess(BeanDefinitionBuilder builder, Element element) { if (!builder.getBeanDefinition().hasAttribute("resourceLoaderPath")) { // 默认视图路径 builder.getBeanDefinition().setAttribute("resourceLoaderPath", "/WEB-INF/"); } }
进入到这个方法org.springframework.web.servlet.config.CorsBeanDefinitionParser#parse
@Override public BeanDefinition parse(Element element, ParserContext parserContext) { Map<String, CorsConfiguration> corsConfigurations = new LinkedHashMap<String, CorsConfiguration>(); // 解析映射 List<Element> 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()); } }
进入到这个方法org.springframework.web.cors.CorsConfiguration#applyPermitDefaultValues
public CorsConfiguration applyPermitDefaultValues() { if (this.allowedOrigins == null) { this.addAllowedOrigin(ALL); } if (this.allowedMethods == null) { this.setAllowedMethods(Arrays.asList( HttpMethod.GET.name(), HttpMethod.HEAD.name(), HttpMethod.POST.name())); } if (this.allowedHeaders == null) { this.addAllowedHeader(ALL); } if (this.allowCredentials == null) { this.setAllowCredentials(true); } if (this.maxAge == null) { this.setMaxAge(1800L); } return this; }
进入到这个方法org.springframework.web.servlet.config.MvcNamespaceUtils#registerCorsConfigurations
public static RuntimeBeanReference registerCorsConfigurations( Map<String, CorsConfiguration> corsConfigurations, ParserContext context, Object source) { // mvcCorsConfigurations 跨域支持bean定义解析 if (!context.getRegistry().containsBeanDefinition(CORS_CONFIGURATION_BEAN_NAME)) { RootBeanDefinition corsDef = new RootBeanDefinition(LinkedHashMap.class); corsDef.setSource(source); corsDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); if (corsConfigurations != null) { corsDef.getConstructorArgumentValues().addIndexedArgumentValue(0, corsConfigurations); } // 注册mvcCorsConfigurations bean定义 context.getReaderContext().getRegistry().registerBeanDefinition(CORS_CONFIGURATION_BEAN_NAME, corsDef); context.registerComponent(new BeanComponentDefinition(corsDef, CORS_CONFIGURATION_BEAN_NAME)); } else if (corsConfigurations != null) { BeanDefinition corsDef = context.getRegistry().getBeanDefinition(CORS_CONFIGURATION_BEAN_NAME); corsDef.getConstructorArgumentValues().addIndexedArgumentValue(0, corsConfigurations); } return new RuntimeBeanReference(CORS_CONFIGURATION_BEAN_NAME); }
往上返回到这个方法org.springframework.web.servlet.config.CorsBeanDefinitionParser#parse
说到最后
本次源码解析仅代表个人观点,仅供参考。