springmvc源码解析MvcNamespaceHandler之视图控制器、状态码控制器

说在前面

本次主要介绍springmvc配置解析<mvc:view-controller/>、<mvc:redirect-view-controller/>、<mvc:status-controller/>。

 

springmvc配置解析

本次介绍MvcNamespaceHandler。

进入到这个方法org.springframework.web.servlet.config.ViewControllerBeanDefinitionParser#parse

@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#registerHandlerMapping

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

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

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.ViewControllerBeanDefinitionParser#parse

 

说到最后

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

 

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值