說在前面web
本次主要介紹springmvc配置解析<mvc:view-controller/>、<mvc:redirect-view-controller/>、<mvc:status-controller/>。spring
springmvc配置解析跨域
本次介紹MvcNamespaceHandler。mvc
進入到這個方法org.springframework.web.servlet.config.ViewControllerBeanDefinitionParser#parseapp
@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<String, BeanDefinition> urlMap; if (hm.getPropertyValues().contains("urlMap")) { urlMap = (Map<String, BeanDefinition>) hm.getPropertyValues().getPropertyValue("urlMap").getValue(); } else { urlMap = new ManagedMap<String, BeanDefinition>(); hm.getPropertyValues().add("urlMap", urlMap); } urlMap.put(element.getAttribute("path"), controller); return null; }
進入到這個方法org.springframework.web.servlet.config.ViewControllerBeanDefinitionParser#registerHandlerMappingcors
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#registerPathMatcheride
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#registerUrlPathHelperurl
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#registerCorsConfigurationsspa
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#registerDefaultComponentscode
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.ViewControllerBeanDefinitionParser#parse
說到最後
本次源碼解析僅表明我的觀點,僅供參考。