1. 程式人生 > >SpringBoot啟動過程

SpringBoot啟動過程

bean 核心 factor register war com inf ... autoconf

一 啟動過程

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

啟動類使用了註解SpringBootApplication,而事實上,該註解是一個組合註解

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication

SpringBootApplication= SpringBootConfiguration + EnableAutoConfiguration + ComponentScan

  • SpringBootConfiguration:配置類

  • EnableAutoConfiguration:能夠實現自動配置的靈魂所在
  • ComponentScan:用註解實現自動掃描,默認掃描當前包與子包,[email protected]是排除兩個類

1 SpringBootConfiguration

基本上該註解的功能類似於 @Configuration,主要功能是標註當前類是一個配置類,該類會聲明一個或者多個@Bean並註入到Spring容器當中

2 EnableAutoConfiguration

該註解是SpringBootApplication能夠自動進行配置的關鍵所在,在Spring框架下的所有@Enable樣式的Annotation其做事的理念和方式是一脈相承的的。簡單開闊一下就是,借助@Import進行收集和註冊特定場景相關的@Bean。

其中Import關鍵字的意義是

  1. 聲明一個bean
  2. 導入@Configuration註解的配置類
  3. 導入ImportSelector的實現類
  4. 導入ImportBeanDefinitionRegister的實現類

EnableAutoConfiguration的本質功能就是通過@Import,將所有符合自動配置的@Bean加載到IoC容器當中

@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

}

其中@Import註解導入了EnableAutoConfigurationImportSelector類,其作用是當容器刷新時,調用AutoConfigurationImportSelector類的selectImports方法,將SpringBoot應用所有滿足符合條件的@Configuration配置都自動加載到當前 IoC容器當中

技術分享圖片

這裏可以看到,本質上真正的自動配置的核心類是SpringFactoriesLoader。該類的主要做用是從指定的配置文件META-INF/spring.factories中加載配置

   public abstract class SpringFactoriesLoader {
    public static <T> List<T> loadFactories(Class<T> factoryClass, ClassLoader classLoader)     {
        ...
    }
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
      ....
  }
}  

3ComponentScan

SpringBoot啟動過程