SpringBoot系列(一):第2章SpringBoot 的依赖和自动配置解析

前言

本次主要对spring-boot-starter-web中pom.xml来解析SpringBoot为什么在很少的配置下就能运行起来?

pom.xml



  4.0.0
  
    org.springframework.boot
    spring-boot-starters
    2.0.3.RELEASE
  
  org.springframework.boot
  spring-boot-starter-web
  2.0.3.RELEASE
  Spring Boot Web Starter
  Starter for building web, including RESTful, applications using Spring
		MVC. Uses Tomcat as the default embedded container
  https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-starters/spring-boot-starter-web
  
    Pivotal Software, Inc.
    https://spring.io
  
  
    
      Apache License, Version 2.0
      http://www.apache.org/licenses/LICENSE-2.0
    
  
  
    
      Pivotal
      [email protected]
      Pivotal Software, Inc.
      http://www.spring.io
    
  
  
    scm:git:git://github.com/spring-projects/spring-boot.git/spring-boot-starters/spring-boot-starter-web
    scm:git:ssh://[email protected]/spring-projects/spring-boot.git/spring-boot-starters/spring-boot-starter-web
    http://github.com/spring-projects/spring-boot/spring-boot-starters/spring-boot-starter-web
  
  
    Github
    https://github.com/spring-projects/spring-boot/issues
  
  
    
    
      org.springframework.boot
      spring-boot-starter
      2.0.3.RELEASE
      compile
    
    
    
    
      org.springframework.boot
      spring-boot-starter-json
      2.0.3.RELEASE
      compile
    

    
    
      org.springframework.boot
      spring-boot-starter-tomcat
      2.0.3.RELEASE
      compile
    

   
    
      org.hibernate.validator
      hibernate-validator
      6.0.10.Final
      compile
    

   
    
      org.springframework
      spring-web
      5.0.7.RELEASE
      compile
    

   
    
      org.springframework
      spring-webmvc
      5.0.7.RELEASE
      compile
    
  

从上面的pom.xml可以看出,dang当我们导入web开发场景的时候(spring-boot-starter-web)它会通过Maven对应的资源加载到我们的工程中,这就会形成了依赖。此时我在开发web应用基本资源都有了。

 

从一个类看SpringBoot的自动配置

以DipatcherServletAutoConfiguration 部分源码来探究,自动配置原理。


@AutoConfigureOrder(-2147483648)
@Configuration
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({DispatcherServlet.class})
@AutoConfigureAfter({ServletWebServerFactoryAutoConfiguration.class})
@EnableConfigurationProperties({ServerProperties.class})
public class DispatcherServletAutoConfiguration {
    public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet";
    public static final String DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME = "dispatcherServletRegistration";

    public DispatcherServletAutoConfiguration() {
    }

    。。。。。。。   
    
    // @Conditional 这个类存在 这个方法就会生效
    // @ConditionalOnClass 没有这个类,这个方法就生效

    @Configuration
    @Conditional({DispatcherServletAutoConfiguration.DispatcherServletRegistrationCondition.class})
    @ConditionalOnClass({ServletRegistration.class})
    @EnableConfigurationProperties({WebMvcProperties.class})
    @Import({DispatcherServletAutoConfiguration.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 multipartConfigProvider) {
            this.serverProperties = serverProperties;
            this.webMvcProperties = webMvcProperties;
            this.multipartConfig = (MultipartConfigElement)multipartConfigProvider.getIfAvailable();
        }

        @Bean(
            name = {"dispatcherServletRegistration"}
        )
        @ConditionalOnBean(
            value = {DispatcherServlet.class},
            name = {"dispatcherServlet"}
        )
        public ServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet) {
            ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet, new String[]{this.serverProperties.getServlet().getServletMapping()});
            registration.setName("dispatcherServlet");
            registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup());
            if (this.multipartConfig != null) {
                registration.setMultipartConfig(this.multipartConfig);
            }

            return registration;
        }
    }

    @Configuration
    @Conditional({DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition.class})
    @ConditionalOnClass({ServletRegistration.class})
    @EnableConfigurationProperties({WebMvcProperties.class})
    protected static class DispatcherServletConfiguration {
        private final WebMvcProperties webMvcProperties;
        private final ServerProperties serverProperties;

        public DispatcherServletConfiguration(WebMvcProperties webMvcProperties, ServerProperties serverProperties) {
            this.webMvcProperties = webMvcProperties;
            this.serverProperties = serverProperties;
        }

        @Bean(
            name = {"dispatcherServlet"}
        )
        public DispatcherServlet dispatcherServlet() {
            DispatcherServlet dispatcherServlet = new DispatcherServlet();
            dispatcherServlet.setDispatchOptionsRequest(this.webMvcProperties.isDispatchOptionsRequest());
            dispatcherServlet.setDispatchTraceRequest(this.webMvcProperties.isDispatchTraceRequest());
            dispatcherServlet.setThrowExceptionIfNoHandlerFound(this.webMvcProperties.isThrowExceptionIfNoHandlerFound());
            return dispatcherServlet;
        }

        @Bean
        @ConditionalOnBean({MultipartResolver.class})
        @ConditionalOnMissingBean(
            name = {"multipartResolver"}
        )
        public MultipartResolver multipartResolver(MultipartResolver resolver) {
            return resolver;
        }

        @Bean
        public DispatcherServletPathProvider mainDispatcherServletPathProvider() {
            return () -> {
                return this.serverProperties.getServlet().getPath();
            };
        }
    }
}

通过上述代码,演示可以看出在SpringBoot内部已经为我们做了很多DispatcherServlet的配置,其中@EnableConfigurationProperties 还能够在读取配置内容情况下自动生成SpringMVC所需的类。至此,我们应该清楚了,为什么几乎没怎么配置SpringBoot救恩能够启动SpringMVC的项目,这些都是SpringBoot通过maven依赖找到对应的jar包和嵌入的服务器,然后使用默认的自动配置类,来启动默认的开发环境。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(SpringBoot,Spring)