SpringBoot基礎篇配置信息之如何讀取配置信息

更多Spring文章,歡迎點擊 一灰灰Blog-Spring專題java

SpringBoot極大的減小了配置,開一個新項目時,徹底能夠作到什麼配置都不加,就能夠直接跑,簡單方便的同時,就帶來了一個問題git

  • 怎麼知道這些默認的配置是什麼?
  • 若是要修改默認配置怎麼辦?
  • 如何添加自定義的配置?
  • 如何讀取這些配置?

<!-- more -->github

I. 配置信息讀取

首先建立一個SpringBoot項目,這一塊就直接省略掉,下面直奔主題,如何獲取配置spring

1. 配置文件

默認讀取配置文件 application.properties 或者 application.yml 中的配置信息,兩種不一樣的文件類型,對應的內部配置方式也不太同樣json

配置文件位置app

通常來講,默認的配置文件application.properties或者application.yml文件放在目錄dom

src/main/resources/

properties格式spring-boot

properties配置文件屬於比較常見的一種了,定義也比較簡單,形如 key=value,一個實例以下學習

#服務端口號
server.port=8081

app.proper.key=${random.uuid}
app.proper.id=${random.int}
app.proper.value=test123

app.demo.val=autoInject

yml格式測試

yml格式的配置文件是以縮進來表示分層,kv之間用冒號來分割,形如

#服務端口號
server:
  port: 8081

app:
  proper:
    key: ${random.uuid}
    id: ${random.int}
    value: test123

  demo:
    val: autoInject

格式對比

兩種不一樣格式的配置文件,有啥區別?

單純從使用來說,並無特別的不一樣,並且我我的也一直這麼認爲的,直到遇到了一個詭異的問題,後面給出

2. 配置讀取

程序啓動以後,如何獲取配置文件application.yml中的配置信息呢?在實際的使用中,最多見的有三種姿式

a. Environment 讀取

全部的配置信息,都會加載到Environment實體中,所以咱們能夠經過這個對象來獲取系統的配置,經過這種方式不只能夠獲取application.yml配置信息,還能夠獲取更多的系統信息

使用姿式以下:

@RestController
public class DemoController {
    @Autowired
    private Environment environment;
 
    @GetMapping(path = "show")
    public String show() {
        Map<String, String> result = new HashMap<>(4);
        result.put("env", environment.getProperty("server.port"));
        return JSON.toJSONString(result);
    }
}

b. @Value 註解方式

@Value註解能夠將配置信息注入到Bean的屬性,也是比較常見的使用方式,但有幾點須要額外注意

  • 若是配置信息不存在會怎樣?
  • 配置衝突了會怎樣(即多個配置文件中有同一個key時)?

使用方式以下,主要是經過 ${},大括號內爲配置的Key;若是配置不存在時,給一個默認值時,能夠用冒號分割,後面爲具體的值

@RestController
public class DemoController {
    // 配置必須存在,且獲取的是配置名爲 app.demo.val 的配置信息
    @Value("${app.demo.val}")
    private String autoInject;

    // 配置app.demo.not不存在時,不拋異常,給一個默認值data
    @Value("${app.demo.not:dada}")
    private String notExists;

    @GetMapping(path = "show")
    public String show() {
        Map<String, String> result = new HashMap<>(4);
        result.put("autoInject", autoInject);
        result.put("not", notExists);
        return JSON.toJSONString(result);
    }
}

c. 對象映射方式

上面的兩種方式對於某幾個特別的配置來講,一個一個的寫還好,若是配置特別多時,每個都去這麼玩,估計會敲的鍵盤原地爆炸了,固然這麼不友好的事情,怎麼能忍!所以就有了下面這種使用方式

@Data
@Component
@ConfigurationProperties(prefix = "app.proper")
public class ProperBean {
    private String key;
    private Integer id;
    private String value;
}

上面的寫法,含義是將配置文件中配置 app.proper.key, app.proper.id, app.proper.value三個配置的值,賦值給上面的bean

  • 即經過註解ConfigurationProperties來制定配置的前綴
  • 經過Bean的屬性名,補上前綴,來完整定位配置信息的Key,並獲取Value賦值給這個Bean

上面這個過程,配置的注入,從有限的經驗來看,多半是反射來實現的,因此這個Bean屬性的Getter/Setter方法得加一下,上面藉助了Lombok來實現,標一個@Component表示這是個Bean,託付給Spring的ApplicationConttext來管理

3. 讀取測試

配置文件application.properties信息以下

#服務端口號
server.port=8081

app.proper.key=${random.uuid}
app.proper.id=${random.int}
app.proper.value=test123

app.demo.val=autoInject

user.name=一灰灰Blog

寫一個DemoController來返回讀取的配置值

@RestController
public class DemoController {
    @Autowired
    private Environment environment;
    @Autowired
    private ProperBean properBean;

    @Value("${app.demo.val}")
    private String autoInject;

    @Value("${app.demo.not:dada}")
    private String notExists;

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

    @GetMapping(path = "show")
    public String show() {
        Map<String, String> result = new HashMap<>(6);
        result.put("properBean", properBean.toString());
        result.put("autoInject", autoInject);
        result.put("env", environment.getProperty("server.port"));
        result.put("not", notExists);
        result.put("name", name);
        return JSON.toJSONString(result);
    }
}

訪問後輸出以下

{
    "autoInject": "autoInject",
    "name": "user",
    "not": "dada",
    "env": "8081",
    "properBean": "ProperBean(key=d4f49141-fa67-4e4c-9e23-c495ff02fda7, id=132483528, value=test123)"
}

請注意上面的notname返回

  • 屬性notExists對應的配置信息,在配置文件中沒有定義,因此返回默認的data
  • 屬性name對應的配置信息 user.nameapplication.properties文件中是一灰灰Blog,可是返回了user(測試環境爲mac,mac系統的用戶名爲user,爲啥叫user?由於某某人...)
    • 形成這個的根源是application.properties的配置被更高優先級的系統配置覆蓋了

4. 小結

前面主要介紹了常見的三種獲取配置信息的方式,但遺留了幾個問題

  • 配置信息讀取的優先級問題(爲何 user.name 配置被覆蓋?)
  • 如何讀取其餘配置文件如 xxx.properties 的配置信息(能讀取麼?)
  • 配置文件中的 ${random.int} 是什麼鬼?
  • SpringBoot的默認配置是些啥

II. 其餘

0. 項目

1. 一灰灰Blog

一灰灰的我的博客,記錄全部學習和工做中的博文,歡迎你們前去逛逛

2. 聲明

盡信書則不如,已上內容,純屬一家之言,因我的能力有限,不免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激

3. 掃描關注

一灰灰blog

QrCode

知識星球

goals

相關文章
相關標籤/搜索