spring boot啟動流程


Springboot是基於Spring4的條件注冊的一套快速開發整合包。它並不是用來替代Spring的解決方案,而是和Spring框架緊密結合用於提升Spring開發者體驗的工具;

SpringBoot的項目啟動類只有一個注解@SpringBootApplication和一個run方法。

@SpringBootApplication

public class Application {

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

}

直接點進@SpringBootApplication

@SpringBootApplication:

包含了@SpringBootConfiguration(打開是@Configuration),

@EnableAutoConfiguration,

@ComponentScan注解。

@Configuration

這里的啟動類標注了@Configuration之后,本身其實也是一個IoC容器的配置類。任何一個標注@Configuration的Java類定義都是一個JavaConfig配置類。任何一個標注了@Bean的方法,其返回值將作為一個bean定義注冊到Spring的IoC容器,方法名將默認成該bean定義的id。

@ComponentScan

@ComponentScan的功能其實就是自動掃描並加載符合條件的組件(比如@Component和@Repository等)或者bean定義,最終將這些bean定義加載到IoC容器中。可以通過basePackages等屬性來細粒度的定制@ComponentScan自動掃描的范圍如果不指定,則默認Spring框架實現會從聲明@ComponentScan所在類的package進行掃描。

@EnableAutoConfiguration

最關鍵的是@Import的幫助,將所有符合自動配置條件的bean定義加載到IoC容器。該配置模塊的主要使用到了SpringFactoriesLoader。

SpringFactoriesLoader詳解

SpringFactoriesLoader為Spring工廠加載器,該對象提供了loadFactoryNames方法,入參為factoryClass和classLoader即需要傳入工廠類名稱和對應的類加載器,方法會根據指定的classLoader,加載該類加器搜索路徑下的指定文件,即spring.factories文件,傳入的工廠類為接口,而文件中對應的類則是接口的實現類,或最終作為實現類。獲取到這些實現類的類名后,loadFactoryNames方法返回類名集合,方法調用方得到這些集合后,再通過反射獲取這些類的類對象、構造方法,最終生成實例。

AutoConfigurationImportSelector

該類主要關注selectImports方法

public String[] selectImports(AnnotationMetadata annotationMetadata) {
  if (!this.isEnabled(annotationMetadata)) {
      return NO_IMPORTS;
  } else {
      AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
      AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
      return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
  }
}

該方法在springboot啟動流程——bean實例化前被執行,返回要實例化的類信息列表。如果獲取到類信息,spring可以通過類加載器將類加載到jvm中,現在我們已經通過spring-boot的starter依賴方式依賴了我們需要的組件,那么這些組件的類信息在select方法中就可以被獲取到。

其中最重要的是getAutoConfigurationEntry里邊調用了getCandidateConfigurations方法

 

 

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
   List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
   Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
   return configurations;
}

其返回一個自動配置類的類名列表,方法調用了loadFactoryNames方法,查看該方法

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
   String factoryTypeName = factoryType.getName();
   return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}

自動配置器會跟根據傳入的factoryClass.getName()到項目系統路徑下所有的spring.factories文件中找到相應的key,從而加載里面的類。

 

借鑒來自: 作者:祖大帥 鏈接:https://juejin.im/post/5b679fbc5188251aad213110 來源:掘金

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM