Spring Boot--yml/properties配置文件以及部分源碼

我的博客: aaatao66.github.io/

開發環境:php

  • win10
  • jdk1.8
  • idea2019
  • maven 3.2.5
  • Spring Boot v2.1.5.RELEASE (版本)

1. yml文件的語法概覽:

person:
 lastNAME: carson
 age: 18
 boss: true
 birth: 1234/12/12
  #map寫法: {k: v,k2: v2}
 maps: {k1: v1,k2: v2}
  #數組寫法: -值
 lists:
 - lisi
 - zhangsan
 - wangwu
 - zhaoliu
 dog:
 name: 小狗
 age: 3

spring:
 mvc:
 view:
 prefix: /WEB-INF/views/
 suffix: .jsp
 datasource:
 url: jdbc:mysql:///ssm
 username: root
 password: root
 driver-class-name: com.mysql.jdbc.Driver
 jpa:
 hibernate:
 ddl-auto: update

server:
 port: 9090
複製代碼

2. @Value獲取值和 @ConfigurationProperties獲取值比較

@ConfigurationProperties @Value
批量注入配置文件中的屬性 功能 一個個指定
支持 鬆散綁定(鬆散語法)大小寫 不支持
不支持 SpEL表達式 支持
支持 JSR303數據校驗 不支持
支持 複雜類型封裝 不支持

這兩種方式都能獲取值:html

  • 若是,咱們只是在某個業務邏輯中須要獲取一下配置文件中的某項值,使用@Value
  • 若是,咱們專門編寫了一個javaBean來和配置文件進行映射;@ConfigurationProperties

@Validatedjava

@Valuemysql

@Getter@Setter
@ToString
@Component
//@ConfigurationProperties (prefix = "person")
@Validated // 來校驗數據,若是數據異常則會統一拋出異常,方便異常中心統一處理。
public class Person {

    // @Email
    @Value("${person.lastNAME}")
    private String lastNAME;
    @Value("#{3*3}")
    private Integer age;
    private Boolean boss;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;

    private Dog dog;
}
複製代碼

3. @PropertySource&@ImportResource

由於 @ConfigurationProperties 是全局註解,若是想指定的話git

  • @PropertySource:能夠指定某個文件 @PropertySource("classpath: xxx.properties)

@ImportResource: 導入Spring配置文件,讓配置文件裏面的內容生效github

  • 建立一個HelloService 類
    • 若是沒有註解狀況下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="helloService" class="com.carson.springboot.service.impl.HelloService"></bean>
</beans>
複製代碼
@Autowired
    ApplicationContext ioc;

    @Test
    public void testHelloService(){
        // 是不是包含 這個 bean
        boolean b = ioc.containsBean("helloService");
        System.out.println(b);//false
    }
複製代碼

false 說明Spring Boot 裏面沒有Spring的配置文件,咱們本身編寫的配置文件,也不能自動識別spring

若是想讓Spring的配置文件生效,加載進來; 就 把@ImportResource標註在一個配置類上sql

  • 主類
@ImportResource(locations = {"classpath:beans.xml"})
@SpringBootApplication
public class SpringbootApplication {

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

}
複製代碼
@Autowired
    ApplicationContext ioc;

    @Test
    public void testHelloService(){
        // 是不是包含 這個 bean
        boolean b = ioc.containsBean("helloService");
        System.out.println(b);//true
    }
複製代碼

SpringBoot推薦給容器中添加組件的方式:數據庫

使用 @Bean數組

  • 1, 配置類======Spring配置文件
    • 建一個包 config,專門放配置類:MyAppConfig
/** * @Configuration: 指明當前類是一個配置類;就是來代替以前的Spring配置文件 * * 之前配置文件總 用 <bean></bean> 標籤添加組件 */
@Configuration
public class MyAppConfig {

    // 將方法的返回值添加到容器中,容器中這幾個組件默認的id就是方法名
    @Bean
    public HelloService helloService(){
        return new HelloService();
    }
}
複製代碼

記得把以前主類的@ImportResource註解 去掉!

輸出結果:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.1.5.RELEASE) 2019-06-29 16:53:48.081 INFO 11084 --- [ main] c.c.s.SpringbootApplicationTests : Starting SpringbootApplicationTests on DESKTOP-JBSD6AK with PID 11084 (started by My in F:\code\springboot) 2019-06-29 16:53:48.083 INFO 11084 --- [ main] c.c.s.SpringbootApplicationTests : No active profile set, falling back to default profiles: default 2019-06-29 16:53:52.689 INFO 11084 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2019-06-29 16:53:53.988 INFO 11084 --- [ main] c.c.s.SpringbootApplicationTests : Started SpringbootApplicationTests in 7.259 seconds (JVM running for 10.759) true 2019-06-29 16:53:54.433 INFO 11084 --- [ Thread-3] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor' 複製代碼

也是 true

4. 配置文件裏的 ${}

random隨機數

${random.value}
${random.int}
${random.long}
${random.int(10)}
${random.int[1024,65536]}
複製代碼

${} 獲取 以前配置的值

person:
 lastNAME: bob${random.uuid}
 age: ${random.int}
 boss: true
 birth: 1234/12/12
 maps: {k1: v1,k2: v2}
 lists:
 - lisi
 - zhangsan
 - wangwu
 - zhaoliu
 dog:
 name: ${person.lastNAME}_dog
 age: 3
複製代碼

若是

 dog:
name: ${person.lastNAME}_dog
複製代碼

若是lastNAME沒有的話, 那就

 dog:
name: ${person.lastNAME:hello}_dog
複製代碼

5. Profile

5.1 多個Profile 文件

Profile是Spring對不一樣環境提供不一樣配置功能的支持,能夠經過指定參數等方式快速切換環境

好比我配置3個端口,一個默認的,一個dev(開發),一個prod(測試)

主配置文件名能夠是 application.yml/application.properties

默認使用application.yml的配置;

5.2 yml的多文檔塊

以 --- 分隔 文檔快

spring:
  profiles:
    active: dev 

server:
  port: 9090
---

server:
  port: 9091
spring:
  profiles: dev 
---

server:
  port: 9092
spring:
  profiles: prod
複製代碼
  • active:是指定哪一個文檔快
  • profiles: 指定一個名稱,讓active識別的

5.3 激活指定profile

1, 在配置文件中指定 spring.profiles.active=dev

2, 命令行:

idea功能欄中的 run > edit > program arguments 添加上

--spring.profiles.active=prod

--spring.profiles.active=dev

3,cmd中 將 項目打成 jar包

java -jar (jar包名) --spring.profiles.active=prod

4, 虛擬機 參數:

idea功能欄中的 run > edit >VM options 添加上

-Dspring.profiles.active=prod/dev


6.Spring Boot配置文件的加載位置

Spring Boot 啓動會掃描如下位置的application.yml或application.properties文件做爲默認配置文件

  • file: ./config/
  • file: ./
  • classpath: ./config/
  • classpath: /

以上是按照優先級從高到低的順序,全部的配置文件都會被加載,高優先級配置會覆蓋 低優先級配置

file : 跟src平級的目錄

classpath: resources目錄下的

咱們也能夠經過配置spring.config.location來改變默認配置文件位置:

1.將項目打包

2.命令行格式: java -jar 包名 --spring.config.location= F:/app/application.properties(配置文件絕對路徑)

項目打包以後可能後來會須要修改一些配置,就可使用這種方式,而且舊配置還會存在,新配置也會應用上

7.外部配置加載順序

SpringBoot也能夠從如下位置加載配置,優先級從高到低,高優先級覆蓋低優先級,若是有不一樣的配置,就會造成互補

  1. 命令行參數

    java -jar xxx.jar --server.port=8081 --xxx

    多個配置用空格分開: --xxx --xxx

  2. 來自java:comp/env的NDI屬性

  3. Java系統屬性(System.getProperties())

  4. 操做系統環境變量

  5. RandomValuePropertySource配置的random.*屬性值

由jar包外向jar包內進行尋找:

優先加載帶profile的

  1. jar包"外"部的application-{profile}.properties或application.yml(帶spring.profile)的配置文件
  2. jar包''內''部的application-{profile}.properties或application.yml(帶spring.profile)的配置文件

再來加載不帶profile的

  1. jar包''外''部的application.properties或application.yml(不帶spring.profile)的配置文件
  2. jar包''內''部的application.properties或application.yml(不帶spring.profile)的配置文件

還有其餘的:

  1. @Configuration註解類上的@PropertySource
  2. 經過SrpingApplication.setDefaultProperties指定默認屬性

詳情參考官網文檔的第 24章

8.自動配置原理(重點)

自動配置到底能些什麼?怎麼寫?自動配置原理:

文檔地址

查看目錄最後一章 X. Appendices

這裏面說明了都有哪些配置項

其實:

  • 1.SpringBoot啓動會加載大量的自動配置類
  • 2.咱們看咱們須要的功能有沒有SpringBoot默認寫好的自動配置類
  • 3.咱們再來看這個自動配置類到底配置了哪些組件(只要咱們要用的組件有,咱們就不須要再來配置了)
  • 4.給容器中自動配置類添加組建的時候,會從properties類中獲取某些屬性,咱們就能夠在配置文件中指定這些屬性的值

xxxxAutoConfigurartion: 自動配置類;

給容器中添加組件

xxxxProperties:封裝配置文件中相關屬性;

技巧:

idea雙擊Shift,搜索 *AutoConfiguration

點開緩存相關的自動配置

咱們將會看到如下源碼:

@EnableConfigurationProperties({CacheProperties.class})
@AutoConfigureAfter({CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class, HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class})
@Import({CacheAutoConfiguration.CacheConfigurationImportSelector.class})
public class CacheAutoConfiguration {
    public CacheAutoConfiguration() {
    }
複製代碼

ctrl+鼠標左鍵點擊:

@EnableConfigurationProperties({CacheProperties.class})
//點擊 CacheProperties
複製代碼

咱們會看到在CacheProperties類上:

@ConfigurationProperties(
    prefix = "spring.cache"
)
public class CacheProperties {
複製代碼

prefix = "spring.cache" : 就是在yml/properties配置文件的語法前綴

至於能配置哪些具體東西?

就是這些

或者你能夠利用idea的代碼提示在配置文件裏,好比我調用 第一個getType

這就是經過源碼的方式,來了解到咱們能夠在配置文件裏配置什麼東西

好比我想鏈接數據庫,我來搜索一下

我看到了咱們的須要的字段,以及下面不少的方法(這裏就不截圖了)

接下來就是到配置文件配置了:

9.細節

@Conditional派生註解

我發現源碼中有不少的 @ConditionalOn***

它其實就是利用Spring底層的 @Conditional註解

做用: 必須是 @Conditional 指定的條件成立,纔給容器中添加組件,配置類裏面的內容纔會生效,若是返回false那麼,你配的東西都不會生效的

SpringBoot 擴展了 @Conditional註解 好比:

因此其實自動配置類必須在必定的條件下才能生效

咱們該怎麼知道哪些類生效哪些沒生效呢?很簡單,在配置文件裏添加:

debug: true	
複製代碼

而後運行咱們的朱類:

​ 咱們會看到:

還有:

都會在控制檯打印輸出
相關文章
相關標籤/搜索