Spring Boot 參考指南(SpringApplication)

23. SpringApplication

SpringApplication類提供了一種方便的方法來引導從main()方法開始的Spring應用程序。在許多狀況下,你能夠委託給靜態SpringApplication.run方法,以下例所示:html

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

當你的應用程序啓動時,你應該看到相似於如下輸出的內容:java

.   ____          _            __ _ _
   /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
  ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
   \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
    '  |____| .__|_| |_|_| |_\__, | / / / /
   =========|_|==============|___/=/_/_/_/
   :: Spring Boot ::   v2.0.5.RELEASE
  2013-07-31 00:08:16.117  INFO 56603 --- [
   Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
  2013-07-31 00:08:16.166  INFO 56603 --- [main]
   ationConfigServletWebServerApplicationContext : Refreshing
   org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
@6e5a8246:startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
  2014-03-04 13:09:54.912  INFO 41370 --- [main] .t.TomcatServletWebServerFactory : Server
   initialized with port: 8080
  2014-03-04 13:09:56.501  INFO 41370 --- [main] o.s.b.s.app.SampleApplication :
   Started SampleApplication in 2.992 seconds (JVM running for 3.658)

默認狀況下,顯示INFO日誌消息,包括一些相關的啓動細節,好比啓動應用程序的用戶。若是你須要一個除INFO以外的日誌級別,你能夠設置它,如第26.4節所述,「日誌級別」git

23.1 啓動失敗

若是你的應用程序啓動失敗,註冊的FailureAnalyzers將有機會提供專用的錯誤消息和解決問題的具體操做。例如,若是你在端口8080上啓動web應用程序,而且該端口已經在使用,你應該會看到相似於如下消息的內容:github

***************************
APPLICATION FAILED TO START
***************************

Description:

Embedded servlet container failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
Spring Boot提供了大量的 FailureAnalyzer實現,你也能夠添加本身的。

若是沒有故障分析器可以處理的異常,你仍然能夠顯示完整的狀況報告,以便更好地理解錯誤,要作到這一點,你須要爲org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener啓用debug屬性啓用DEBUG日誌記錄web

例如,若是你正在使用java -jar運行你的應用程序,你可使啓用debug屬性以下:算法

$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug

23.2 自定義橫幅

在啓動時打印的橫幅能夠經過添加banner.txt文件到你的類路徑或設置spring.banner.location屬性指向該文件的位置。若是文件的編碼不是UTF-8,那麼能夠設置spring.banner.charset。除了一個文本文件,你還能夠添加一個banner.gifbanner.jpgbanner.png圖像文件到你的類路徑或設置spring.banner.image.location屬性。圖像被轉換成ASCII藝術表示,並打印在任何文本標題之上。spring

在你的banner.txt文件,你可使用如下任何一個佔位符:編程

表23.1. Banner變量segmentfault

變量 描述
${application.version} MANIFEST.MF中聲明的應用程序的版本號,例如,Implementation-Version:1.0被打印爲1.0
${application.formatted-version} 應用程序的版本號,如在MANIFEST.MF中聲明並格式化以供顯示(包含了括號和前綴v),例如(v1.0)
${spring-boot.version} 你正在使用的Spring Boot版本,例如2.0.5.RELEASE
${spring-boot.formatted-version} 你正在使用的Spring Boot版本,格式化用於顯示(用括號括起來,並以v爲前綴),例如(v2.0.5.RELEASE)
${Ansi.NAME}${AnsiColor.NAME} NAME是ANSI轉義代碼的名稱,有關詳細信息,請參閱AnsiPropertySource
${application.title} 你的應用程序的標題,如聲明的那樣,在MANIFEST.MF中,例如,Implementation-Title:MyApp被打印爲MyApp
若是你想以編程的方式生成橫幅,則可使用 SpringApplication.setBanner(…)方法,使用 org.springframework.boot.Banner接口和實現你本身的 printBanner()方法。

你也能夠用spring.main.banner-mode屬性肯定橫幅是否必須打印在系統上System.out(console),發送到已配置的日誌記錄器(log),或根本沒有生成(off)。api

在如下名稱中,打印的橫幅被註冊爲一個單例bean:springBootBanner

YAML映射 offfalse,因此若是你想要禁用應用程序中的banner,請確保添加引號,以下例所示:
spring: 
  main:
    banner-mode: "off"

23.3 定製SpringApplication

若是SpringApplication的默認值不符合你的喜愛,你能夠建立一個本地實例並自定義它,例如,要關閉橫幅,你能夠寫:

public static void main(String[] args) {
   SpringApplication app = new 
   SpringApplication(MySpringConfiguration.class); 
   app.setBannerMode(Banner.Mode.OFF);
   app.run(args);
}
傳遞給 SpringApplication的構造函數參數是Spring bean的配置源,在大多數狀況下,這些都是對 @Configuration類的引用,可是它們也能夠是對XML配置的引用,或者對應該被掃描的包的引用。

還可使用application.properties配置SpringApplication,詳見第24節,外部化配置

有關配置選項的完整列表,請參見SpringApplication Javadoc

23.4 Fluent構建器API

若是你須要構建ApplicationContext層次結構(包含parentchild關係的多個上下文),或者你更喜歡使用「fluent」構建器API,那麼你可使用SpringApplicationBuilder

SpringApplicationBuilder容許你將多個方法調用連接在一塊兒,幷包含讓你建立層次結構的父類和子方法,以下例所示:

new SpringApplicationBuilder()
        .sources(Parent.class)
        .child(Application.class)
        .bannerMode(Banner.Mode.OFF)
        .run(args);
在建立 ApplicationContext層次結構時,有一些限制,例如,Web組件必須包含在子上下文內,而且在父類和子上下文環境中都使用相同的 Environment,請參閱 SpringApplicationBuilder Javadoc瞭解詳細信息。

23.5 應用程序事件和監聽

除了一般的Spring框架事件,好比ContextRefreshedEvent以外,SpringApplication還會發送一些附加的應用程序事件。

在建立 ApplicationContext以前,實際上觸發了一些事件,所以不能將偵聽器註冊爲 @Bean。你可使用 SpringApplication.addListeners(...) 方法或 SpringApplicationBuilder.listeners(...)方法註冊它們。若是你但願這些監聽器自動註冊,無論應用程序是如何建立的,你均可以添加一個 META-INF/spring.factories文件到你的項目,並經過使用 org.springframework.context.ApplicationListener key來引用你的監聽器,以下例所示:

org.springframework.context.ApplicationListener=com.example.project.MyListener

應用程序事件按如下順序發送:

  1. 一個ApplicationStartingEvent是在運行開始時發送的,可是在任何處理以前,除了偵聽器和初始化器的註冊以外。
  2. 在建立上下文以前,當Environment在上下文中被使用時,就會發送一個ApplicationEnvironmentPreparedEvent
  3. 一個ApplicationPreparedEvent是在刷新開始以前發送的,可是在加載了bean定義以後。
  4. 在調用上下文以後發送一個ApplicationStartedEvent,可是在調用任何應用程序和命令行運行程序以前。
  5. 在調用任何應用程序和命令行運行程序後,將發送一個ApplicationReadyEvent,它代表應用程序已經準備好服務請求。
  6. 若是啓動時出現異常,則發送ApplicationFailedEvent
你一般不須要使用應用程序事件,可是知道它們的存在是很方便的。在內部,Spring Boot使用事件來處理各類任務。

使用Spring Framework的事件發佈機制發送應用程序事件,該機制的一部分確保在子環境中發佈給偵聽器的事件也會在任何祖先上下文中被髮布給監聽器。所以,若是你的應用程序使用了SpringApplication實例的層次結構,那麼偵聽器可能會接收到相同類型的應用程序事件的多個實例。

爲了讓你的偵聽器區分事件的上下文和派生上下文的事件,它應該請求將其應用程序上下文注入,而後將注入的上下文與事件上下文進行比較,能夠經過實現ApplicationContextAware或若是偵聽器是bean,經過使用@Autowired來注入上下文。

23.6 Web環境

SpringApplication試圖爲你建立合適的ApplicationContext類型,用於肯定WebEnvironmentType的算法至關簡單:

  • 若是Spring MVC存在,則使用AnnotationConfigServletWebServerApplicationContext
  • 若是Spring MVC不存在,Spring WebFlux是存在的,那麼就使用一個AnnotationConfigReactiveWebServerApplicationContext
  • 不然,AnnotationConfigApplicationContext被使用。

這意味着若是你使用Spring MVC和來自Spring WebFlux的新WebClient在相同的應用程序中,Spring MVC將在默認狀況下使用,你能夠經過調用setWebApplicationType(WebApplicationType)來輕鬆覆蓋它。

還能夠調用setApplicationContextClass(…)徹底控制所使用的ApplicationContext類型。

在JUnit測試中使用 SpringApplication時,一般須要調用 setWebApplicationType(WebApplicationType.NONE)

23.7 訪問應用程序參數

若是你須要訪問傳遞給SpringApplication.run(…)的應用程序參數,你能夠注入一個org.springframework.boot.ApplicationArguments bean,ApplicationArguments接口提供了對原始String[]參數以及解析optionnon-option參數的訪問,以下例所示:

import org.springframework.boot.*;
import org.springframework.beans.factory.annotation.*; 
import org.springframework.stereotype.*;

@Component
public class MyBean {

   @Autowired
   public MyBean(ApplicationArguments args) {
      boolean debug = args.containsOption("debug");
      List<String> files = args.getNonOptionArgs();
      // if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
   } 
}
Spring Boot還會在Spring Environment中註冊一個 CommandLinePropertySource,這容許你使用 @Value註解注入單個應用程序參數。

23.8 使用ApplicationRunner或CommandLineRunner

若是你須要在SpringApplication啓動以後運行一些特定的代碼,你能夠實現ApplicationRunnerCommandLineRunner接口,兩個接口都以相同的方式工做,並提供了一個單獨的run方法,在SpringApplication.run(…)完成以前調用。

CommandLineRunner接口提供對應用程序參數的訪問做爲一個簡單的字符串數組,而ApplicationRunner使用前面討論的ApplicationArguments接口。下面的示例展現了一個使用run方法的CommandLineRunner:

import org.springframework.boot.*; 
import org.springframework.stereotype.*;

@Component
public class MyBean implements CommandLineRunner {

   public void run(String... args) { 
   // Do something...
   } 

}

若是定義了多個CommandLineRunnerApplicationRunner bean,必須以特定的順序調用它們,那麼你能夠額外地實現org.springframework.core.Ordered接口或使用org.springframework.core.annotation.Order註解。

23.9 應用程序退出

每一個SpringApplication都向JVM註冊一個關閉hook以確保ApplicationContext在退出時優雅地關閉。可使用全部標準的Spring生命週期回調函數(如DisposableBean接口或@PreDestroy註解)。

此外,當SpringApplication.exit()被調用時若是但願返回特定的退出代碼則bean能夠實現org.springframework.boot.ExitCodeGenerator接口。而後能夠將此退出代碼傳遞給System.exit(),以將其做爲狀態代碼返回,以下面的示例所示:

@SpringBootApplication
public class ExitCodeApplication {

   @Bean
   public ExitCodeGenerator exitCodeGenerator() { 
      return () -> 42;
   }

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

}

此外,ExitCodeGenerator接口也能夠由異常來實現,當遇到這樣的異常時,Spring Boot返回由實現的getExitCode()方法提供的退出代碼。

23.10 管理功能

經過指定spring.application.admin.enabled屬性能夠爲應用程序啓用與admin相關的特性,這將在平臺MBeanServer上公開SpringApplicationAdminMXBean,你可使用該特性遠程管理你的Spring Boot應用程序,這個特性還能夠用於任何服務wrapper實現。

若是你想知道應用程序正在運行哪一個HTTP端口,請使用 local.server.port的鍵獲取該屬性。
在啓用該特性時要注意,由於 MBean公開了關閉應用程序的方法。

上一篇:開發者工具

下一篇:外部化配置

相關文章
相關標籤/搜索