Spring Boot 學(xué)習(xí)03-----Spring Boot 特性

接著來學(xué)習(xí)Spring Boot,雖然現(xiàn)在很困。

SpringApplication

SpringApplication 類提供了一種方便的方式從main()方法中啟動(dòng)應(yīng)用,在許多情況下,你可以用SpringApplication.run這個(gè)靜態(tài)方法。如下所示:

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

默認(rèn)的日志級(jí)別是INFO 級(jí)別。

啟動(dòng)失敗

如果你的應(yīng)用啟動(dòng)失敗,則注冊(cè)的FailureAnalyzers會(huì)提供專門的錯(cuò)誤信息和具體操作來解決問題。例如,你應(yīng)用的端口8080被占用,你將會(huì)看到如下信息:

***************************
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.

可以通過命令行開啟調(diào)試模式

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

自定義Banner

可以通過添加 banner.txt文件改變應(yīng)用啟動(dòng)時(shí)打印的banner,這個(gè)文件要添加到classpath下,如果不在classpath下,需要通過spring.banner.location 來指定該文件的位置。如果該文件的編碼不是UTF-8,你需要設(shè)置spring.banner.charset 。另外,你可以添加banner.gif, banner.jpg, or banner.png等圖片文件到你的classpath下或者通過spring.banner.image.location 來設(shè)置。更多知識(shí)參見 banner

自定義SpringApplication

如果默認(rèn)的SpringApplication 不滿足你的需求,你可以創(chuàng)建一個(gè)局部變量,然后自定義它,例如:你想關(guān)閉banner,你可以

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(MySpringConfiguration.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
}

流式構(gòu)建API

如果你需要構(gòu)建一個(gè)ApplicationContext 分層(多個(gè)有父子關(guān)系的contexts)或者你更想用一個(gè)”fluent” 構(gòu)建API,你可以使用SpringApplicationBuilder。
這個(gè)SpringApplicationBuilder 讓多個(gè)方法可以鏈?zhǔn)秸{(diào)用。包括父方法和子方法,如下所示:

new SpringApplicationBuilder()
        .sources(Parent.class)
        .child(Application.class)
        .bannerMode(Banner.Mode.OFF)
        .run(args);

注意:創(chuàng)建ApplicationContext時(shí)有一些限制。例如:web的組成元素中必須包含子context,父context和子context必須使用相同的環(huán)境。

應(yīng)用的事件和監(jiān)聽器

除了Spring Framework 自帶的事件以外,例如ContextRefreshedEvent,SpringApplication 還添加了一些額外的應(yīng)用事件。
注意:一些事件實(shí)際上在創(chuàng)建ApplicationContext之前已經(jīng)被觸發(fā)。所以你不能通過@Bean注冊(cè)這些監(jiān)聽器。你可以通過SpringApplication.addListeners(…?) 方法或者通過SpringApplicationBuilder.listeners(…?) 方法。如果你想這些監(jiān)聽器被自動(dòng)注冊(cè),你可以在你的項(xiàng)目中添加一個(gè)META-INF/spring.factories 文件。例如你可以

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

應(yīng)用事件在下面的列表中,當(dāng)你的應(yīng)用運(yùn)行后:
1. ApplicationStartingEvent: 在運(yùn)行開始時(shí)發(fā)送,但是在注冊(cè)listeners 和注冊(cè)初始化器之后。
2. ApplicationEnvironmentPreparedEvent 當(dāng)已經(jīng)知道要使用的上下文(context)環(huán)境,并在context創(chuàng)建之前。
3. ApplicationPreparedEvent在啟動(dòng) 刷新之前,但在加載bean定義之后。
4. ApplicationStartedEvent 上下文被刷新,但是應(yīng)用和命令行運(yùn)行被喚起。
5. ApplicationReadyEvent 應(yīng)用和命令行被喚起。并且處理了相關(guān)的回調(diào)以指示應(yīng)用程序準(zhǔn)備好服務(wù)請(qǐng)求。
6. ApplicationFailedEvent 當(dāng)啟動(dòng)時(shí)出現(xiàn)異常時(shí)。
注意:一般您不需要使用應(yīng)用程序時(shí)間,但可以方便的知道它們存在,在內(nèi)部,Spring Boot使用事件來處理各種任務(wù)。

Web環(huán)境

SpringApplication 將代替您創(chuàng)建一個(gè)正確的的ApplicationContext,默認(rèn)的,會(huì)創(chuàng)建一個(gè)AnnotationConfigApplicationContext或者AnnotationConfigServletWebServerApplicationContext具體取決于你開發(fā)的Web 應(yīng)用。
用于確定”Web環(huán)境”的算法是相當(dāng)簡(jiǎn)單的(基于幾個(gè)類的存在)。如果需要覆蓋默認(rèn),可以設(shè)置setWebEnvironment(boolean webEnvironment)
也可以通過調(diào)用setApplicationContextClass()對(duì)ApplicationContext完全控制。
注意:在Junit測(cè)試匯總常常需要setWebEnvironment(false)

訪問應(yīng)用程序參數(shù)

如果你需要訪問傳遞給SpringApplication.run()的應(yīng)用程序參數(shù),則可以注入org.springframework.boot.ApplicationArguments bean。ApplicationArguments 接口提供對(duì)原始String[]參數(shù)以及解析選項(xiàng)和非選項(xiàng)參數(shù)的訪問:

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 也注冊(cè)了CommandLinePropertySource,這個(gè)可以讓你可以通過@Value注解注入簡(jiǎn)單應(yīng)用參數(shù)。

使用ApplicationRunner 或者CommandLineRunner

SpringApplication啟動(dòng)時(shí)如果您需要運(yùn)行一些特定的代碼, 就可以實(shí)現(xiàn)ApplicationRunnerCommandLineRunner接口。兩個(gè)接口都以相同的方式工作,并提供一個(gè)單獨(dú)的運(yùn)行方式,這將SpringApplication.run(...) 完成之前調(diào)用。

外部配置

Spring Boot 允許您外部化您的配置,以便您可以在不同的環(huán)境中使用相同的應(yīng)用程序代碼。您可以使用properties文件,YAML文件,環(huán)境變量和命令行參數(shù)來外部化配置,可以使用@Value注釋將屬性值直接注入到您的bean中。該注釋可通過Spring環(huán)境(Environment)抽象訪問,或通過@ConfigurationProperties 綁定到結(jié)構(gòu)化對(duì)象
Spring Boot 使用非常特別的PropertySource命令,旨在允許合理的覆蓋值。屬性按以下順序選擇。
1. 在您的HOME目錄設(shè)置的Devtools全局屬性(~/.spring-boot-devtools.properties)。
2. 單元測(cè)試中的@TestPropertySource注解。
3. 單元測(cè)試中的 @SpringBootTest#properties 注解屬性
4. 命令行參數(shù)
5. SPRING_APPLICATION_JSON 中的屬性值(內(nèi)嵌JSON嵌入到環(huán)境變量或系統(tǒng)屬性中)
6. ServletConfig 初始化參數(shù)
7. ServletContext 初始化參數(shù)
8. 來自java:comp/env 的JNDI屬性
9. Java系統(tǒng)屬性(System.getProperties())
10. 操作系統(tǒng)環(huán)境變量
11. RandomValuePropertySource,只有隨機(jī)的屬性 random.* 中。
12. jar包外面的 Profile-specific application properties (application- {profile} .properties和YAML變體)
13. jar包內(nèi)的 Profile-specific application properties (application-{profile}.properties和YAML變體)
14. jar包外的應(yīng)用屬性文件(application.properties和YAML變體)。
15. jar包內(nèi)的應(yīng)用屬性文件(application.properties和YAML變體)。
16. 在@Configuration 上@PropertySource注解
17. 默認(rèn)屬性(使用SpringApplication.setDefaultProperties設(shè)置)。
例如:假設(shè)你正在開發(fā)一個(gè)使用name屬性的@Component

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

@Component
public class MyBean {

    @Value("${name}")
    private String name;

    // ...

}

在應(yīng)用程序類路徑(例如:您的jar中),您可以擁有一個(gè)application.properties,它為name屬性提供了默認(rèn)屬性值。在新環(huán)境中運(yùn)行時(shí),可以再您的jar外部提供了一個(gè)application.properties 來覆蓋 name屬性。對(duì)于一次性測(cè)試,您可以使用特定的命令行開關(guān)啟動(dòng)(例如:java -jar app.jar -name=”Spring”)。

SPRING_APPLICATION_JSON屬性可以在命令行中提供一個(gè)環(huán)境變量。 例如在UN*X shell中:

$ SPRING_APPLICATION_JSON='{"foo":{"bar":"spam"}}' java -jar myapp.jar

配置隨機(jī)值

RandomValuePropertySource 可用于注入隨機(jī)值(例如,進(jìn)入秘密或測(cè)試用例)。它可以產(chǎn)生整數(shù),uuid或字符串,例如:

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

random.int *語法是 OPEN value (,max) CLOSE ,其中OPEN,CLOSE是任何字符和值,max是整數(shù)。 如果提供max,則值為最小值,max為最大值(獨(dú)占)。

應(yīng)用程序?qū)傩晕募?/h3>

SpringApplication 將從以下位置的 application.propeties文件中加載屬性,并將它們添加到Spring Environment中:
1. 當(dāng)前目錄的/config 子目錄
2. 當(dāng)前目錄
3. classpath 中/config包
4. classpath root路徑
該列表按照優(yōu)先級(jí)從高到低排序。
也可以 使用YAML(’.yml’)文件 替代”.properties”。

properties文件中的占位符

application.properties中的值在使用時(shí)通過已有的環(huán)境進(jìn)行過濾。以便您可以引用之前定義的值。例如:

app.name=MyApp
app.description=${app.name} is a Spring Boot application

您也可以使用此技術(shù)創(chuàng)建現(xiàn)有Spring Boot屬性的“簡(jiǎn)寫“。 有關(guān)詳細(xì)信息,請(qǐng)參見第72.4節(jié)“使用”短命令行參數(shù)“how-to”。

使用YAML 替代Properties

YAML 是JSON的超集,因此這是分層配置數(shù)據(jù)一種非常方便的格式。每當(dāng)您的類路徑中都有SnakeYAML 庫時(shí)。SpringApplication類將自動(dòng)支持YAML作為properties的替代方法。

加載YAML

Spring Framework提供了兩個(gè)方便的類,可用于加載YAML文檔。YamlPropertiesFactoryBean將YAML作為Properties加載,YamlMapFactoryBean將YAML作為Map加載。
例如,下面YAML文檔:

environments:
    dev:
        url: http://dev.bar.com
        name: Developer Setup
    prod:
        url: http://foo.bar.com
        name: My Cool App

將轉(zhuǎn)化為屬性:

environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App

YAML列表表示為具有[index] dereferencers的屬性鍵,例如YAML:

my:
   servers:
       - dev.bar.com
       - foo.bar.com

將轉(zhuǎn)化為屬性:

my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com

將YAML作為Spring環(huán)境中的屬性文件

可以使用YamlPropertySourceLoader類在Spring環(huán)境中將YAML作為PropertySource暴露出來。這允許你使用熟悉@Value注解和占位符語法來訪問YAML屬性。

多個(gè)YAML文件

您可以使用spring.profiles.active鍵指定單個(gè)文件中的多個(gè)特定配置文件YAML文檔,以指示文檔何時(shí)應(yīng)用。

YAML的缺點(diǎn)

YAML文件無法通過@PropertySource注解 加載。因此,在需要以這種方式加載值的情況下,需要使用Properties文件。

Spring Boot的特性就暫時(shí)介紹到此處。

參考

https://blog.csdn.net/qq_36348557/article/details/69396589
https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/reference/htmlsingle/#boot-features-external-config


作者:碼農(nóng)飛哥

微信公眾號(hào):碼農(nóng)飛哥