SpringBoot啓動過程

一 啓動過程

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

Spring的啓動代碼裏最核心的兩個部分java

  • @SpringBootApplication
  • SpringApplication.run()

二 @SpringBootApplication

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

@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

事實上,將這個註解拆開看,能夠獲得springboot

SpringBootApplication= SpringBootConfiguration + EnableAutoConfiguration + ComponentScanapp

咱們能夠稱之爲三體結構框架

  • SpringBootConfiguration:配置類
  • EnableAutoConfiguration:可以實現自動配置的靈魂所在
  • ComponentScan:用註解實現自動掃描,默認掃描當前包與子包, @Filter是排除兩個類

1 SpringBootConfiguration

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

2 EnableAutoConfiguration

該註解是SpringBootApplication可以自動進行配置的關鍵所在,在Spring框架下的全部@Enable樣式的Annotation其作事的理念和方式是一脈相承的的。簡單歸納一下就是,藉助@Import進行收集和註冊特定場景相關的@Bean。component

其中Import關鍵字的意義是blog

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

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

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

}

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

這裏能夠看到,本質上真正的自動配置的核心類是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) {
        ....
    }
}

3 ComponentScan

@ComponentScan會掃描指定的包路徑,若是沒有指定包路徑,則以聲明的這個註解類做爲基本包路徑。

相關文章
相關標籤/搜索