SpringApplication執行流程


SpringApplication類的直接作用是在main方法中通過自有的run方法啟動spring應用。

具體的run方法為:

public static ConfigurableApplicationContext run(Object source, String... args)

該方法最終會把source傳給SpringApplication的構造方法中的初始化方法:

private void initialize(Object[] sources) {

   if (sources != null && sources.length > 0) {

      this.sources.addAll(Arrays.asList(sources));

   }

   this.webEnvironment = deduceWebEnvironment();

   setInitializers((Collection) getSpringFactoriesInstances(

         ApplicationContextInitializer.class));

   setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

   this.mainApplicationClass = deduceMainApplicationClass();

}

該初始化方法一共做了以下幾件事:

一、判斷sourse長度

首先,如果sources長度大於0(即是數組或容器),則把這些sources全部傳到內置的hashset中。由此可見,run方法的第一個參數中是可以傳入多個source的。

 

二、判斷web環境是否正確

this.webEnvironment = deduceWebEnvironment();

判斷整個環境中是否存在javax.servlet.Servlet類和

org.springframework.web.context.ConfigurableWebApplicationContext類這兩個類,如果存在話,則表示web環境正常,返回true,否則返回false。

 

三、設置Initializers

首先會調getSpringFactoriesInstances方法加載ApplicationContextInitializer類,這個方法最終會運行SpringFactoriesLoader.loadFactoryNames方法,這個方法的目的是從“META-INF/spring.factories文件”中加載配置。

可實際上我們一般在開發springboot項目時並沒有創建過spring.factories文件,可還是自動加載了各種配置,原因如下:

在項目的main方法上一般都會設置@SpringBootApplication注解,@SpringBootApplication注解中包含了多個注解,其中有一個@EnableAutoConfiguration注解尤為重要。

通過@EnableAutoConfiguration注解會將org.springframework.boot.autoconfigure.EnableAutoConfiguration這個包作為查找META-INF/spring.factories文件的根目錄,即spring.factories文件會從org.springframework.boot.autoconfigure.EnableAutoConfiguration包中查找。而這個包里面自然有已經寫好的spring.factories文件了。

整個springboot中會看到很多@Enable開頭的注解,所有的@Enable開頭的注解的作用都是通過@Import將“特定的bean”加載到Ioc容器中。@EnableAutoConfiguration的作用就是通過SpringFactoriesLoader將所有的標注了@Configuration注解的類加載(既有boot.autoconfigure包自帶的標注了@Configuration的類,也可以是自己創建的標注了@Configration的類,都會被作為配置加載)

 

四、設置Listeners

listener的加載與之前的Initializers加載同理,都是尋找META-INF/spring.factories文件,然后被@EnableAutoConfiguration注解把路徑轉移到了org.springframework.boot.autoconfigure.EnableAutoConfiguration/META-INF/spring.factories中,之后就能找到已經提前寫好的相關監聽配置了。

 

五、設置mainApplicationClass

private Class<?> deduceMainApplicationClass() {

   try {

      StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();

      for (StackTraceElement stackTraceElement : stackTrace) {

         if ("main".equals(stackTraceElement.getMethodName())) {

            return Class.forName(stackTraceElement.getClassName());

         }

      }

   }

   catch (ClassNotFoundException ex) {

      // Swallow and continue

   }

   return null;

}

該方法是通過遍歷棧,找到main方法,從而找到啟動類,並將其賦值給mainApplicationClass屬性。

 


免責聲明!

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



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