欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot加載配置文件的實現(xiàn)方式總結(jié)

 更新時間:2022年03月23日 09:18:39   作者:鴨血粉絲Tang  
在實際的項目開發(fā)過程中,我們經(jīng)常需要將某些變量從代碼里面抽離出來,放在配置文件里面,以便更加統(tǒng)一、靈活的管理服務(wù)配置信息。所以本文將為大家總結(jié)一下SpringBoot加載配置文件的常用方式,需要的可以參考一下

一、簡介

在實際的項目開發(fā)過程中,我們經(jīng)常需要將某些變量從代碼里面抽離出來,放在配置文件里面,以便更加統(tǒng)一、靈活的管理服務(wù)配置信息。比如,數(shù)據(jù)庫、eureka、zookeeper、redis、mq、kafka 等服務(wù)組件的連接參數(shù)配置,還有我們自定義的項目參數(shù)配置變量。

當(dāng)然,實際上根據(jù)當(dāng)前的業(yè)務(wù)需求,我們往往會自定義參數(shù),然后注入到代碼里面去,以便靈活使用!

今天,我們就一起來聊一聊SpringBoot加載配置文件的幾種玩法!

SpringBoot 項目在啟用時,首先會默認(rèn)加載bootstrap.properties或者bootstrap.yml這兩個配置文件(這兩個優(yōu)先級最高);接著會加載application.properties或application.yml;如果何配置了spring.profiles這個變量,同時還會加載對應(yīng)的application-{profile}.properties或者application-{profile}.yml文件,profile為對應(yīng)的環(huán)境變量,比如dev,如果沒有配置,則會加載profile=default的配置文件。

雖然說配置項都寫在同一個配置文件沒有問題,但是很多時候我們?nèi)匀幌M芊珠_寫,這樣會比較清晰,比如zookeeper的配置寫在zookeeper.properties,數(shù)據(jù)庫相關(guān)的配置寫在datasource.properties等等,因此就需要設(shè)置加載外部配置文件!

具體該如何實現(xiàn)呢,我們一起來看看!

二、代碼實踐

2.1、通過@value注解實現(xiàn)參數(shù)加載

當(dāng)我們想要在某個類里面注入某個變量,通過@value注解就可以簡單實現(xiàn)參數(shù)的注入!

例如application.properties文件里,配置一個config.name的變量key,值為zhangsan;

//參數(shù)定義
config.name=zhangsan

然后在對應(yīng)的類里面,通過參數(shù)@value注入即可!

@RestController
public class HelloController {
 
    @Value("${config.name}")
    private String config;

    @GetMapping("config")
    public String config(){
        return JSON.toJSONString(config);
    }
}

使用@value注解注入配置,通常情況下有個要求就是,注解里面的變量,必須在application.properties文件里面事先定義好,否則啟動報錯!

當(dāng)然,如果我們不想讓它抱錯,我們可以給它一個缺省值xxx,比如:

@Value("${config.name:xxx}")
private String config;

這樣,SpringBoot 項目在啟用時不會報錯!

2.2、通過@ConfigurationProperties注解實現(xiàn)參數(shù)加載

某些場景下,@value注解并不能滿足我們所有的需求,比如參數(shù)配置的數(shù)據(jù)類型是一個對象或者數(shù)組,這個時候才用@ConfigurationProperties會是一個比較好的選擇!

配置一個對象類型的參數(shù)

例如在application.properties文件里,當(dāng)我們想配置一個對象類型的參數(shù),我們可以這樣操作!

//參數(shù)定義
config2.name=demo_1
config2.value=demo_value_1

然后,創(chuàng)建一個配置類Config2,用于將定義的變量映射到配置類里面。

@Component
@ConfigurationProperties(prefix = "config2")
public class Config2 {

    public String name;

    public String value;

    //...get、set
}

讀取數(shù)據(jù)的方式,也很簡單,直接注入到對應(yīng)的類里面就可以了;

@RestController
public class HelloController {
 
    @Autowired
    private Config2 config2;

    @GetMapping("config2")
    public String config2(){
        return JSON.toJSONString(config2);
    }
}

配置一個Map類型的參數(shù)

例如在application.properties文件里,當(dāng)我們想配置一個 Map 類型的參數(shù),我們可以這樣操作!

//參數(shù)定義
config3.map1.name=demo_id_1_name
config3.map1.value=demo_id_1_value
config3.map2.name=demo_id_2_name
config3.map2.value=demo_id_2_value

然后,創(chuàng)建一個配置類Config3,用于將定義的變量映射到配置類里面。

@Component
@ConfigurationProperties(prefix = "config3")
public class Config3 {

    private Map<String, String> map1 = new HashMap<>();

    private Map<String, String> map2 = new HashMap<>();

    //...get、set
}

讀取數(shù)據(jù)的方式,與之類似!

@RestController
public class HelloController {
 
    @Autowired
    private Config3 config3;

    @GetMapping("config3")
    public String config3(){
        return JSON.toJSONString(config3);
    }
}

配置一個List類型的參數(shù)

例如在application.properties文件里,當(dāng)我們想配置一個 List 類型的參數(shù),我們可以這樣操作!

//參數(shù)定義
config4.userList[0].enable=maillist_1_enable
config4.userList[0].name=maillist_1_name
config4.userList[0].value=maillist_1_value

config4.userList[1].enable=maillist_2_enable
config4.userList[1].name=maillist_2_name
config4.userList[1].value=maillist_2_value

config4.userList[2].enable=maillist_3_enable
config4.userList[2].name=maillist_3_name
config4.userList[2].value=maillist_3_value

然后,創(chuàng)建一個配置類Config4,用于將定義的變量映射到配置類里面。

@Component
@ConfigurationProperties(prefix = "config4")
public class Config4 {

    private List<UserEntity> userList;

    public List<UserEntity> getUserList() {
        return userList;
    }

    public void setUserList(List<UserEntity> userList) {
        this.userList = userList;
    }
}
public class UserEntity {

    private String enable;
    private String name;
    private String value;

    //...get、set
}

讀取數(shù)據(jù)的方式,與之類似!

@RestController
public class HelloController {
 
    @Autowired
    private Config4 config4;

    @GetMapping("config4")
    public String config4(){
        return JSON.toJSONString(config4);
    }
}

2.3、通過@PropertySource注解實現(xiàn)配置文件加載

正如我們最開始所介紹的,很多時間,我們希望將配置文件分卡寫,比如zookeeper組件對應(yīng)的服務(wù)配置文件是zookeeper.properties,redis組件對應(yīng)的服務(wù)配置文件是redis.properties等等。

這種自定義的配置文件,我們應(yīng)該如何加載到Spring容器里面呢?

其實方法也很簡單,通過@PropertySource就可以實現(xiàn)!

首先,我們在resources資源文件夾下,創(chuàng)建兩個配置文件test.properties和bussiness.properties,內(nèi)容如下!

test.properties文件內(nèi)容:

aaa.a1=aa1123
aaa.a2=aa2123
aaa.a3=aa3123
aaa.a4=aa4123

bussiness.properties文件內(nèi)容:

bbbb.a1=bb1123
bbbb.a2=bb2123
bbbb.a3=bb3123
bbbb.a4=bb4123

在SpringBoot啟動類上加載配置文件即可!

@SpringBootApplication
@PropertySource(value = {"test.properties","bussiness.properties"})
public class PropertyApplication {

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

讀取數(shù)據(jù)的方式,與之類似!

@RestController
public class HelloController {
 
    @Value("${aaa.a2}")
    private String a2;

    @Value("${bbbb.a1}")
    private String bbbbA1;
 
    @GetMapping("a2")
    public String a2(){
        return JSON.toJSONString(a2);
    }

    @GetMapping("bbbbA1")
    public String bbbbA1(){
        return JSON.toJSONString(bbbbA1);
    }
}

如果我們只是在業(yè)務(wù)中需要用到自定義配置文件的值,這樣引入并沒有什么問題;但是如果某些自定義的變量,在項目啟動的時候需要用到,這種方式會存在一些問題,原因如下:

翻譯過來的意思就是說:

雖然在@SpringBootApplication上使用@PropertySource似乎是在環(huán)境中加載自定義資源的一種方便而簡單的方法,但我們不推薦使用它,因為SpringBoot在刷新應(yīng)用程序上下文之前就準(zhǔn)備好了環(huán)境。使用@PropertySource定義的任何鍵都加載得太晚,無法對自動配置產(chǎn)生任何影響。

因此,如果某些參數(shù)是啟動項變量,建議將其定義在application.properties或application.yml文件里面,這樣就不會有問題!

或者,采用【自定義環(huán)境處理類】來實現(xiàn)配置文件的加載!

2.4、通過自定義環(huán)境處理類,實現(xiàn)配置文件的加載

實現(xiàn)方法也很簡單,首先,創(chuàng)建一個實現(xiàn)自EnvironmentPostProcessor接口的類,然后自行加載配置文件。

public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {


    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        //自定義配置文件
        String[] profiles = {
                "test.properties",
                "bussiness.properties",
                "blog.yml"
        };

        //循環(huán)添加
        for (String profile : profiles) {
            //從classpath路徑下面查找文件
            Resource resource = new ClassPathResource(profile);
            //加載成PropertySource對象,并添加到Environment環(huán)境中
            environment.getPropertySources().addLast(loadProfiles(resource));
        }
    }

    //加載單個配置文件
    private PropertySource<?> loadProfiles(Resource resource) {
        if (!resource.exists()) {
            throw new IllegalArgumentException("資源" + resource + "不存在");
        }
        if(resource.getFilename().contains(".yml")){
            return loadYaml(resource);
        } else {
            return loadProperty(resource);
        }
    }

    /**
     * 加載properties格式的配置文件
     * @param resource
     * @return
     */
    private PropertySource loadProperty(Resource resource){
        try {
            //從輸入流中加載一個Properties對象
            Properties properties = new Properties();
            properties.load(resource.getInputStream());
            return new PropertiesPropertySource(resource.getFilename(), properties);
        }catch (Exception ex) {
            throw new IllegalStateException("加載配置文件失敗" + resource, ex);
        }
    }

    /**
     * 加載yml格式的配置文件
     * @param resource
     * @return
     */
    private PropertySource loadYaml(Resource resource){
        try {
            YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
            factory.setResources(resource);
            //從輸入流中加載一個Properties對象
            Properties properties = factory.getObject();
            return new PropertiesPropertySource(resource.getFilename(), properties);
        }catch (Exception ex) {
            throw new IllegalStateException("加載配置文件失敗" + resource, ex);
        }
    }
}

接著,在resources資源目錄下,我們還需要創(chuàng)建一個文件META-INF/spring.factories,通過spi方式,將自定義環(huán)境處理類加載到Spring處理器里面,當(dāng)項目啟動時,會自動調(diào)用這個類!

#啟用我們的自定義環(huán)境處理類
org.springframework.boot.env.EnvironmentPostProcessor=com.example.property.env.MyEnvironmentPostProcessor

這種自定義環(huán)境處理類方式,相對會更佳靈活,首先編寫一個通用的配置文件解析類,支持properties和yml文件的讀取,然后將其注入到Spring容器里面,基本上可以做到一勞永逸!

2.5、最后,我們來介紹一下yml文件讀取

在上文中,我們大部分都是以properties為案例進行介紹,可能有的人已經(jīng)踩過坑了,在項目中使用@PropertySource注解來加載yml文件,結(jié)果啟動直接報錯,原因是@PropertySource不支持直接解析yml文件,只能解析properties文件。

那如果,我想單獨解析yml文件,也不想弄一個【自定義環(huán)境處理類】這種方式來讀取文件,應(yīng)該如何處理呢?

操作方式也很簡單,以自定義的blog.yml文件為例!

blog.yml文件內(nèi)容:

pzblog:
  name: helloWorld

然后,創(chuàng)建一個讀取yml文件的配置類

@Configuration
public class ConfigYaml {

    /**
     * 加載YML格式自定義配置文件
     * @return
     */
    @Bean
    public static PropertySourcesPlaceholderConfigurer properties() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
        yaml.setResources(new ClassPathResource("blog.yml"));
        configurer.setProperties(yaml.getObject());
        return configurer;
    }
}

讀取數(shù)據(jù)的方式,與之類似!

@RestController
public class HelloController {
 
    @Value("${pzblog.name}")
    private String pzblogName;

    @GetMapping("pzblogName")
    public String pzblogName(){
        return JSON.toJSONString(pzblogName);
    }
}

三、小結(jié)

本文主要圍繞 SpringBoot 加載配置文件的幾種實現(xiàn)方式,做了一次內(nèi)容總結(jié),如果有遺漏的地方,歡迎網(wǎng)友批評指出!

以上就是SpringBoot加載配置文件的實現(xiàn)方式總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot加載配置文件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • maven倉庫repositories和mirrors的配置及區(qū)別詳解

    maven倉庫repositories和mirrors的配置及區(qū)別詳解

    這篇文章主要介紹了maven倉庫repositories和mirrors的配置及區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 從java反編譯及字節(jié)碼角度探索分析String拼接字符串效率

    從java反編譯及字節(jié)碼角度探索分析String拼接字符串效率

    這篇文章主要介紹了從java反編譯及字節(jié)碼角度探索分析String拼接字符串效率,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • 深入了解Java線程池的原理和監(jiān)控

    深入了解Java線程池的原理和監(jiān)控

    這篇文章主要介紹了深入了解Java線程池的原理和監(jiān)控,創(chuàng)建Java線程需要給線程分配堆棧內(nèi)存以及初始化內(nèi)存,還需要進行系統(tǒng)調(diào)用,頻繁地創(chuàng)建和銷毀線程會大大降低系統(tǒng)的運行效率,這時候就要用到線程池,需要的朋友可以參考下
    2023-07-07
  • java使用dom4j解析xml配置文件實現(xiàn)抽象工廠反射示例

    java使用dom4j解析xml配置文件實現(xiàn)抽象工廠反射示例

    本文主要介紹了java使用dom4j讀取配置文件實現(xiàn)抽象工廠和反射的示例,在Java中也可以同Donet一樣,將差異配置在配置文件里面。另外,我們采用下面的方式實現(xiàn),將會更加便捷
    2014-01-01
  • Java實戰(zhàn)權(quán)限管理系統(tǒng)的實現(xiàn)流程

    Java實戰(zhàn)權(quán)限管理系統(tǒng)的實現(xiàn)流程

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SpringBoot+MyBatis+AOP+LayUI+Mysql實現(xiàn)一個權(quán)限管理系統(tǒng),大家可以在過程中查缺補漏,提升水平
    2022-01-01
  • Java使用Collections.sort對中文進行排序方式

    Java使用Collections.sort對中文進行排序方式

    這篇文章主要介紹了Java使用Collections.sort對中文進行排序方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java并發(fā)內(nèi)存模型詳情

    Java并發(fā)內(nèi)存模型詳情

    這篇文章主要介紹了Java并發(fā)內(nèi)存模型,Java是一門支持多線程執(zhí)行的語言,要編寫正確的并發(fā)程序,了解Java內(nèi)存模型是重要前提。而了解硬件內(nèi)存模型有助于理解程序的執(zhí)行,下面文章就來看看詳細(xì)內(nèi)容吧
    2021-10-10
  • shiro整合springboot前后端分離

    shiro整合springboot前后端分離

    這篇文章主要介紹了shiro整合springboot前后端分離,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • spring boot + mybatis如何實現(xiàn)數(shù)據(jù)庫的讀寫分離

    spring boot + mybatis如何實現(xiàn)數(shù)據(jù)庫的讀寫分離

    這篇文章主要給大家介紹了關(guān)于spring boot + mybatis如何實現(xiàn)數(shù)據(jù)庫的讀寫分離的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Java代理模式之靜態(tài)代理與動態(tài)代理的區(qū)別及優(yōu)缺點

    Java代理模式之靜態(tài)代理與動態(tài)代理的區(qū)別及優(yōu)缺點

    代理模式是一種常用的設(shè)計模式,它允許通過引入一個代理對象來控制對目標(biāo)對象的訪問,在Java中,代理模式被廣泛應(yīng)用,它可以提供額外的功能,如權(quán)限檢查、緩存、日志記錄等,本文將介紹靜態(tài)代理與動態(tài)代理的區(qū)別及優(yōu)缺點,需要的朋友可以參考下
    2023-06-06

最新評論