springboot源碼解析autoconfigure之DispatcherServletAutoConfiguration

說在前面web

本次開始spring-boot-autoconfigure源碼解析之DispatcherServletAutoConfigurationspring

 

源碼解析app

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(EmbeddedServletContainerAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {

   /*
    * The bean name for a DispatcherServlet that will be mapped to the root URL 將映射到根URL的DispatcherServlet的bean名稱"/"
    */
   public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet";
   /*
    * The bean name for a ServletRegistrationBean for the DispatcherServlet DispatcherServlet的ServletRegistrationBean的bean名稱"/"
    */
   public static final String DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME = "dispatcherServletRegistration";
   @Configuration
   @Conditional(DefaultDispatcherServletCondition.class)
   @ConditionalOnClass(ServletRegistration.class)
   @EnableConfigurationProperties(WebMvcProperties.class)
   protected static class DispatcherServletConfiguration {

      private final WebMvcProperties webMvcProperties;
      public DispatcherServletConfiguration(WebMvcProperties webMvcProperties) {
         this.webMvcProperties = webMvcProperties;
      }

//    初始化dispatcherServlet
      @Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
      public DispatcherServlet dispatcherServlet() {
         DispatcherServlet dispatcherServlet = new DispatcherServlet();
         dispatcherServlet.setDispatchOptionsRequest(
               this.webMvcProperties.isDispatchOptionsRequest());
         dispatcherServlet.setDispatchTraceRequest(
               this.webMvcProperties.isDispatchTraceRequest());
         dispatcherServlet.setThrowExceptionIfNoHandlerFound(
               this.webMvcProperties.isThrowExceptionIfNoHandlerFound());
         return dispatcherServlet;
      }

//    初始化multipartResolver
      @Bean
      @ConditionalOnBean(MultipartResolver.class)
      @ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
      public MultipartResolver multipartResolver(MultipartResolver resolver) {
         // Detect if the user has created a MultipartResolver but named it incorrectly 檢測用戶是否建立了一個多部件解析器,但命名不正確
         return resolver;
      }

   }

   @Configuration
   @Conditional(DispatcherServletRegistrationCondition.class)
   @ConditionalOnClass(ServletRegistration.class)
   @EnableConfigurationProperties(WebMvcProperties.class)
   @Import(DispatcherServletConfiguration.class)
   protected static class DispatcherServletRegistrationConfiguration {

      private final ServerProperties serverProperties;
      private final WebMvcProperties webMvcProperties;
      private final MultipartConfigElement multipartConfig;
      public DispatcherServletRegistrationConfiguration(
            ServerProperties serverProperties, WebMvcProperties webMvcProperties,
            ObjectProvider<MultipartConfigElement> multipartConfigProvider) {
         this.serverProperties = serverProperties;
         this.webMvcProperties = webMvcProperties;
         this.multipartConfig = multipartConfigProvider.getIfAvailable();
      }

//    初始化dispatcherServletRegistration
      @Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
      @ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
      public ServletRegistrationBean dispatcherServletRegistration(
            DispatcherServlet dispatcherServlet) {
//       mapping默認是/*
         ServletRegistrationBean registration = new ServletRegistrationBean(
               dispatcherServlet, this.serverProperties.getServletMapping());
         registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
         registration.setLoadOnStartup(
               this.webMvcProperties.getServlet().getLoadOnStartup());
         if (this.multipartConfig != null) {
            registration.setMultipartConfig(this.multipartConfig);
         }
         return registration;
      }

   }

   @Order(Ordered.LOWEST_PRECEDENCE - 10)
   private static class DefaultDispatcherServletCondition extends SpringBootCondition {

      @Override
      public ConditionOutcome getMatchOutcome(ConditionContext context,
            AnnotatedTypeMetadata metadata) {
         ConditionMessage.Builder message = ConditionMessage
               .forCondition("Default DispatcherServlet");
         ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//       根據類型從beanFactory找出DispatcherServlet實現類的beanNames
         List<String> dispatchServletBeans = Arrays.asList(beanFactory
               .getBeanNamesForType(DispatcherServlet.class, false, false));
         if (dispatchServletBeans.contains(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)) {
            return ConditionOutcome.noMatch(message.found("dispatcher servlet bean")
                  .items(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME));
         }
         if (beanFactory.containsBean(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)) {
            return ConditionOutcome
                  .noMatch(message.found("non dispatcher servlet bean")
                        .items(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME));
         }
         if (dispatchServletBeans.isEmpty()) {
            return ConditionOutcome
                  .match(message.didNotFind("dispatcher servlet beans").atAll());
         }
         return ConditionOutcome.match(message
               .found("dispatcher servlet bean", "dispatcher servlet beans")
               .items(Style.QUOTE, dispatchServletBeans)
               .append("and none is named " + DEFAULT_DISPATCHER_SERVLET_BEAN_NAME));
      }

   }

   @Order(Ordered.LOWEST_PRECEDENCE - 10)
   private static class DispatcherServletRegistrationCondition
         extends SpringBootCondition {

      @Override
      public ConditionOutcome getMatchOutcome(ConditionContext context,
            AnnotatedTypeMetadata metadata) {
         ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
         ConditionOutcome outcome = checkDefaultDispatcherName(beanFactory);
         if (!outcome.isMatch()) {
            return outcome;
         }
         return checkServletRegistration(beanFactory);
      }

      private ConditionOutcome checkDefaultDispatcherName(
            ConfigurableListableBeanFactory beanFactory) {
         List<String> servlets = Arrays.asList(beanFactory
               .getBeanNamesForType(DispatcherServlet.class, false, false));
         boolean containsDispatcherBean = beanFactory
               .containsBean(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
         if (containsDispatcherBean
               && !servlets.contains(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)) {
            return ConditionOutcome
                  .noMatch(startMessage().found("non dispatcher servlet")
                        .items(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME));
         }
         return ConditionOutcome.match();
      }

      private ConditionOutcome checkServletRegistration(
            ConfigurableListableBeanFactory beanFactory) {
         ConditionMessage.Builder message = startMessage();
//       從beanFactory中查找ServletRegistrationBean的實現類的beanNames
         List<String> registrations = Arrays.asList(beanFactory
               .getBeanNamesForType(ServletRegistrationBean.class, false, false));
         boolean containsDispatcherRegistrationBean = beanFactory
               .containsBean(DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME);
         if (registrations.isEmpty()) {
            if (containsDispatcherRegistrationBean) {
               return ConditionOutcome
                     .noMatch(message.found("non servlet registration bean").items(
                           DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME));
            }
            return ConditionOutcome
                  .match(message.didNotFind("servlet registration bean").atAll());
         }
         if (registrations
               .contains(DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)) {
            return ConditionOutcome.noMatch(message.found("servlet registration bean")
                  .items(DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME));
         }
         if (containsDispatcherRegistrationBean) {
            return ConditionOutcome
                  .noMatch(message.found("non servlet registration bean").items(
                        DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME));
         }
         return ConditionOutcome.match(message.found("servlet registration beans")
               .items(Style.QUOTE, registrations).append("and none is named "
                     + DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME));
      }

      private ConditionMessage.Builder startMessage() {
         return ConditionMessage.forCondition("DispatcherServlet Registration");
      }

   }

}

 

說在最後ide

本次僅表明我的觀點,僅供參考。spring-boot

相關文章
相關標籤/搜索