最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot自定義yml配置文件及其外部部署過程

 更新時間:2022年03月24日 09:53:04   作者:一個假的程序媛  
這篇文章主要介紹了springboot自定義yml配置文件及其外部部署過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

1、序

背景:有個小項目需要后臺,俺頂著Java菜逼的頭銜接下來了,被男票瘋狂安利spring boot,于是(被逼無奈)開始了邊學邊開發(fā)的躺坑之路……真香,資料超多,超好用!?。?/p>

電廠的項目,用了公司自己開發(fā)的實時數(shù)據(jù)庫,后臺這邊就涉及到很多測點的信息需要存儲到配置文件(為什么不是關系數(shù)據(jù)庫真的不要問我),并且希望在部署的時候方便修改,考慮到內(nèi)容頗多,放在application-pro.yml中實在不合適,就加了個point.yml。倒不是因為現(xiàn)場測點信息會變才需要更改,更多的是突然一拍腦袋,發(fā)現(xiàn)手抖寫錯了?

首先,因為一不小心變成了xxx.yml玩家,好好用哦,沒能回去xxx.properties,傳說中官方不支持像加載xxx.properties配置文件那樣使用注解@PropertySource("classpath:xxx.properties")的方式加載yml配置文件,這里要說的就是加載自定義yml文件的方法。

官方說明看一下

加載自定義xxx.properties文件的方法參考這篇文章:

springBoot中的properties配置解析

注意:之前在找多數(shù)據(jù)源配置的資料時,就因為資料對應的spring boot版本差異搞得很郁悶,請務必注意俺用的版本是:

spring boot 2.13

2、加載自定義yml文件

spring boot的資料非常多,多到非常容易不用動腦就解決了問題呢~項目做完之后冷靜下來,覺得還是應該驗證一下,畢竟打臉是為了以后有頭有臉。

2.1、使用@PropertiesSource注解讀取yml配置文件-簡單版

按照上面給出的官宣,這條路是不行的。因為沒看到文檔對應的版本號,還是試一下:

# 配置文件 point.yml
id: 2233
name: Ellie

(呃,這種信息為啥要叫point啊啊?。?/p>

// 配置對應的config類
@Data
@Configuration
@PropertySource(value = {"classpath:point.yml"})
@ConfigurationProperties()
public class TestPoint {
    private int id;
    private String name;
    @Override
    public String toString() {
        return "TestPoint{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

隨手糊了個controller來測試

@RestController
public class TestConfigController {
    @Resource
    TestPoint testPoint;
    @ApiOperation("測試 配置文件")
    @RequestMapping(value = "/config")
    public ResultBean<String> testConfig() {
        return ResultBeanUtil.makeOkResp(testPoint.toString());
    }
}

postman搞起來

都挺好!

所以如果只是要讀取這樣簡單的信息的話,直接使用注解@PropertiesSource是可以的,官方說的不確定的影響我也不知道是啥哦。

2.2、使用@PropertiesSource注解讀取yml配置文件-不簡單版?

加個list<基礎類型>看看。

# point.yml
id: 2233
name: Ellie
cards:
  - XD02101263
  - ZY8965
  - GX0009
 
 // 配置類
 @Data
@Configuration
@PropertySource(value = {"classpath:point.yml"})
@ConfigurationProperties()
public class TestPoint {
    private int id;
    private String name;
    private List<String> cards;
    @Override
    public String toString() {
        return "TestPoint{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", cards=" + cards +
                '}';
    }
}

postman

裝逼失敗,不行了哦。使用@Value("id")注解也是不行的呢,因為這個注解是用來匹配變量名稱和配置文件不一致的情況。

按照其他博客里講的(才糊代碼一個月根本沒有深入看原理的我只好是:大佬說啥就是啥),是因為使用@PropertySource注解只能加載yml配置文件,但不能將其配置信息暴露給spring environment,需要手動暴露。方法就是在讓application啟動的時候把下面的bean加載。

@Bean
	public static PropertySourcesPlaceholderConfigurer properties() {
		PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
		YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
		yaml.setResources(new ClassPathResource("point.yml"));
		configurer.setProperties(yaml.getObject());
		return configurer;
	}

偷懶的我直接丟到了main函數(shù)所在的.java文件。運行:

真的不是我截錯圖哦。

2.3、加前綴可行版

畢竟我這么機智(無腦分析?。?,悄咪咪加了個前綴,前綴的名字隨意取哈,與配置類中對應即可,我只是偷懶叫做prefix。

# point.yml
prefix:
  id: 2233
  name: Ellie
  cards:
    - XD02101263
    - ZY8965
    - GX0009
 
 // config類
 @Data
@Configuration
@PropertySource(value = {"classpath:point.yml"})
@ConfigurationProperties(prefix = "prefix") 
public class TestPoint {
    private int id;
    private String name;
    private List<String> cards;
    @Override
    public String toString() {
        return "TestPoint{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", cards=" + cards +
                '}';
    }
}

都挺好大結局?

求助:

這樣為什么可行,俺是一點都不曉得的,如果有大佬路過,請幫忙解答?。?!跪謝orz

順便說一句,出于好奇,試了下某些博文里說的前綴加yml分隔符---配合的方式,感覺上是一本正經(jīng)胡說八道,實際上也沒讀出來。讀取List<類>也是同樣可行的。

# point.yml
prefix:
  id: 2233
  name: Ellie
  cards:
    - name: XD
      code: XD02101263
    - name: ZY
      code: ZY8965
    - name: GX
      code: GX0009
      
// config 類
@Data
@Configuration
@PropertySource(value = {"classpath:point.yml"})
@ConfigurationProperties(prefix = "prefix")
public class TestPoint {
    private int id;
    private String name;
    private List<Card> cards;
    @Override
    public String toString() {
        return "TestPoint{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", cards=" + cards +
                '}';
    }
}
// 并不需要有什么與眾不同的card類
@Data
public class Card {
    private String name;
    private String code;
    @Override
    public String toString() {
        return "Card{" +
                "name='" + name + '\'' +
                ", code='" + code + '\'' +
                '}';
    }
}

請求

查找資料的過程中還看到了一種別致的寫法,是為了解決多層嵌套的yml的讀寫,未驗證,因為有選擇的話,我不愿意這樣寫,不過寫法確實很別致,哈哈哈!http://www.fzitv.net/article/242026.htm

3、外部部署

其實就是把配置文件部署在jar包外部,方便修改而不必重新打包。

3.1、spring boot核心配置文件外部加載

希望外部加載自定義配置文件,需要先了解spring默認的文件加載方式。

spring程序會按優(yōu)先級從下面這些路徑來加載application.properties配置文件:

  • 當前目錄下的/config目錄
  • 當前目錄
  • classpath里的/config目錄
  • classpath 根目錄

idea中,在源碼下的classpath對應src/main/resources很明確,打包后的classpath在哪里俺是不知道的,然后就把打包后的jar包解壓看了下,在BOOT-INF\classes下看到了application.yml和point.yml。所以要想覆蓋配置文件,我再jar包同級目錄下建了config文件夾,修改配置文件內(nèi)容看覆蓋是否生效。

具體操作:

  • 打包的時候默認將application.yml和point.yml打包到jar中(classpath)
  • 部署時,jar包同級目錄下建立config文件夾,修改application.yml中端口號和point.yml內(nèi)容,看修改是否生效。

修改后的point.yml文件如下:

prefix:
  id: 2233
  name: FakeEllie
  cards:
    - name: NONE
      code: 00000001

測試結果:端口號修改生效(application.yml修改生效),修改后的point.yml并未生效。

畢竟自定義配置文件,一廂情愿希望spring boot按照核心文件加載方式加載point.yml,沒有生效也在意料之中,不過路并沒有堵死。

3.2、在@PropertySource中添加路徑

查資料的時候注意到還有這種寫法:

@Data
@Configuration
@PropertySource(value = {"file:config/point.yml"})
@ConfigurationProperties(prefix = "prefix")
public class TestPoint {
    private int id;
    private String name;
    private List<Card> cards;
    @Override
    public String toString() {
        return "TestPoint{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", cards=" + cards +
                '}';
    }
}

就是通過file來指定文件路徑,之前是classpath來指定資源相對路徑,說來神奇,這種方式?jīng)]有報錯,但讀取的內(nèi)容卻是classpath下的point.yml,而不是config下的point.yml。

想來是通過@ConfigurationProperties(prefix = "prefix")指定的前綴去classpath下匹配到的。跟@PropertySource(value = {"file:config/point.yml"})大概是沒有關系了,忘崽牛奶真好喝。

3.3、通過YamlPropertiesFactoryBean添加路徑

回想上面的描述,YamlPropertiesFactoryBean是將配置文件暴露給spring環(huán)境的,可以考慮使用它來指定文件路徑。

修改bean,添加new FileSystemResource("config/point.yml")來指定config文件夾下的配置。

@Bean
	public static PropertySourcesPlaceholderConfigurer properties() {
		PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
		YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
		yaml.setResources(new ClassPathResource("point.yml"), new FileSystemResource("config/point.yml"));
		configurer.setProperties(yaml.getObject());
		return configurer;
	}

此時配置類上使用@PropertySource(value = {"file:config/point.yml"})這種寫法,返回的是

成功了?但是好像搞笑了。不過也說明了配置文件讀取的順序。config文件夾下的有最終決定權。

為了直觀些,俺順手修改jar包同級目錄下config文件夾中point.yml配置文件,保證list元素個數(shù)相同:

prefix:
  id: 2233
  name: FakeEllie
  cards:
    - name: NONE
      code: 00000001
    - name: NONE
      code: 00000002
    - name: NONE
      code: 00000003

不搞笑了。

但是,改成此時配置類上使用@PropertySource(value = {"classpath:point.yml"})后,返回并沒有變化。所以YamlPropertiesFactoryBean將配置文件暴露給spring環(huán)境,說的應該就是將文件添加到spring的classpath下了,先讀默認的,再讀新添加這樣子的。

然鵝這樣就沒有辦法在不進行外部配置的時候使用默認的classpath下的配置文件了。

此外,通過YamlPropertiesFactoryBean添加配置文件的方式,就需要保證config/point.yml一定要存在,要想達到不進行外部配置的時候讀取默認classpath下point.yml,在進行外部配置的時候讀取config/point.yml。那就只好耍流氓了。

@Data
@Configuration
@PropertySource(value = {"file:config/point.yml", "classpath:point.yml"}, ignoreResourceNotFound = true)
@ConfigurationProperties(prefix = "prefix")
public class TestPoint {
    private int id;
    private String name;
    private List<Card> cards;
    @Override
    public String toString() {
        return "TestPoint{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", cards=" + cards +
                '}';
    }
}

重點:然后!在不進行外部配置的時候,config/point.yml內(nèi)容為空,或者干脆跟classpath下的point.yml內(nèi)容保持一致。

小孩子才做選擇題,我全都想要

雖然看上去像個意外,但是好在意啊啊啊啊,遏制不住的好奇心啊!就是剛剛那個拼起來的返回值。

想看看是不是application.yml覆蓋list也會這樣,俺把配置類對應的內(nèi)容舉家搬遷到了application.yml中。如下:

// 配置類
@Data
@Configuration
@ConfigurationProperties(prefix = "prefix")
public class TestPoint {
    private int id;
    private String name;
    private List<Card> cards;
    @Override
    public String toString() {
        return "TestPoint{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", cards=" + cards +
                '}';
    }
}

配置類默認讀取application.yml。

# classpath:application.yml
prefix:
  id: 2233
  name: Ellie
  cards:
    - name: XD
      code: XD02101263
    - name: ZY
      code: ZY8965
    - name: GX
      code: GX0009
#config/application.yml
prefix:
  id: 2233
  name: FakeEllie
  cards:
    - name: NONE
      code: 00000001

測試結果:

并沒有進行拼接啊喂?。?!

在各種調換順序看影響的時候,修改了YamlPropertiesFactoryBean添加source的順序,返回結果發(fā)生了變化。

@Bean
	public static PropertySourcesPlaceholderConfigurer properties() {
		PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
		YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
		yaml.setResources(new FileSystemResource("config/point.yml"), new ClassPathResource("point.yml"));
		configurer.setProperties(yaml.getObject());
        configurer.setIgnoreResourceNotFound(true);
		return configurer;
	}

返回結果

有一種簡單的在運行時通過命令參數(shù)指定配置文件的方式效果與此類似。

java -jar demo.jar --Dspring.config.location=point.yml

俺的原則時,代碼能解決的,就不要交給人來解決。

雖然沒有解決任何問題,但是順便知道了讀取的先后順序就是setResources的先后順序。卒

所以目前的結論是,對于有l(wèi)ist的配置,并且個數(shù)發(fā)生變化的時候,這種方式并不適用。

3.4、自定義yaml文件資源加載類

在注解@PropertySource中,有個屬性factory主要用來聲明解析配置文件的類,這個類必須是PropertySourceFactory接口的實現(xiàn)。從這里入手。

參考資料:

Spring Boot自定義加載yml實現(xiàn),附源碼解讀

默認調用的是PropertySourceFactory的實現(xiàn)DefaultPropertySourceFactory,因此可以自定義factory實現(xiàn)PropertySourceFactory接口,也可以擴展DefaultPropertySourceFactory類。兩種寫法的效果是一樣的,列出來。

直接實現(xiàn)PropertySourceFactory接口

public class YamlPropertyLoaderFactory implements PropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) throws IOException {
        List<PropertySource<?>> sources = name != null ? new YamlPropertySourceLoader().load(name, encodedResource.getResource()) : new YamlPropertySourceLoader().load(
                getNameForResource(encodedResource.getResource()), encodedResource.getResource());
        if (sources.size() == 0) {
            return null;
        }
        return sources.get(0);
    }
    private static String getNameForResource(Resource resource) {
        String name = resource.getDescription();
        if (!StringUtils.hasText(name)) {
            name = resource.getClass().getSimpleName() + "@" + System.identityHashCode(resource);
        }
        return name;
    }
}

擴展DefaultPropertySourceFactory

 public class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        if (resource == null) {
            return super.createPropertySource(name, resource);
        }
        List<PropertySource<?>> sources = new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource());
        if (sources.size() == 0) {
            return super.createPropertySource(name, resource);
        }
        return sources.get(0);
    }
}

建議用第二種方式。

用factory的方式來實現(xiàn)的話,前面莫名其妙加個prefix就可以正常讀取的詭異操作也不需要了哦。

使用方式如下:

@Data
@Configuration
@PropertySource(value = {"classpath:point.yml", "file:config/point.yml"}, factory = YamlPropertyLoaderFactory.class, ignoreResourceNotFound = true)
@ConfigurationProperties
public class TestPoint{
    private int id;
    private String name;
    private List<Card> cards;
    @Override
    public String toString() {
        return "TestPoint{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", cards=" + cards +
                '}';
    }
}
# config/point.yml
id: 2233
name: FakeEllie
cards:
  - name: NONE
    code: 00000001

測試結果:

自定義factory的方式,讀取多種路徑的配置文件時,也是有先后順序的,就是@PropertySource中value屬性指定的順序,與使用YamlPropertiesFactoryBean將資源暴露給spring環(huán)境不同,這個不會有前面出現(xiàn)的“拼接”效果出現(xiàn),棒呆~

以解決問題為目標和以寫清楚文章為目標去看同樣的問題,真的是不一樣的探索路徑呢,湊字數(shù)和為了flag不倒的文寫的遠遠超出自己最初的預期,真好,超喜歡!

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • springboot整合騰訊云短信開箱即用的示例代碼

    springboot整合騰訊云短信開箱即用的示例代碼

    這篇文章主要介紹了springboot整合騰訊云短信開箱即用,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Java中ReUtil正則表達式工具庫的使用

    Java中ReUtil正則表達式工具庫的使用

    ReUtil是Hutool庫中的正則表達式工具類,提供了多種常用正則表達式操作方法,下面就來介紹一下ReUtil的使用,具有一定的參考價值,感興趣的可以了解一下
    2025-02-02
  • Spring?Boot?3.2.5集成mysql的詳細步驟記錄

    Spring?Boot?3.2.5集成mysql的詳細步驟記錄

    作為一名Java開發(fā)者,我們經(jīng)常需要在我們的應用程序中使用數(shù)據(jù)庫,在Spring Boot中集成數(shù)據(jù)庫是非常容易的,下面這篇文章主要給大家介紹了關于Spring?Boot?3.2.5集成mysql的詳細步驟,需要的朋友可以參考下
    2024-04-04
  • 一文詳解Spring任務執(zhí)行和調度(小結)

    一文詳解Spring任務執(zhí)行和調度(小結)

    這篇文章主要介紹了一文詳解Spring任務執(zhí)行和調度(小結),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • SpringBoot根據(jù)各地區(qū)時間設置接口有效時間的實現(xiàn)方式

    SpringBoot根據(jù)各地區(qū)時間設置接口有效時間的實現(xiàn)方式

    這篇文章給大家介紹了SpringBoot根據(jù)各地區(qū)時間設置接口有效時間的實現(xiàn)方式,文中通過代碼示例給大家講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-01-01
  • Integer和int的區(qū)別實例詳解

    Integer和int的區(qū)別實例詳解

    這篇文章主要介紹了Integer和int的區(qū)別實例詳解,文字和代碼實例講解的很清楚,有感興趣的同學可以學習下
    2021-03-03
  • @RequestBody獲取不到參數(shù)的問題

    @RequestBody獲取不到參數(shù)的問題

    這篇文章主要介紹了@RequestBody獲取不到參數(shù)的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • kettle中使用js調用java類的方法

    kettle中使用js調用java類的方法

    這篇文章主要介紹了kettle中使用js調用java類的方法,本文講解了注意事項和調用語法,需要的朋友可以參考下
    2015-05-05
  • SpringBoot配置返回數(shù)據(jù)不存在null的問題小結

    SpringBoot配置返回數(shù)據(jù)不存在null的問題小結

    文章介紹了在Spring Boot項目中使用Jackson序列化器處理JSON數(shù)據(jù)時遇到的問題,特別是如何配置Jackson以返回不包含null值的JSON響應,并探討了Jackson的三種主要JSON處理方法,感興趣的朋友一起看看吧
    2025-02-02
  • 使用jenkins+maven+git發(fā)布jar包過程詳解

    使用jenkins+maven+git發(fā)布jar包過程詳解

    這篇文章主要介紹了使用jenkins+maven+git發(fā)布jar包過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-07-07

最新評論

敖汉旗| 齐齐哈尔市| 贵港市| 申扎县| 夏津县| 娱乐| 巴彦县| 岳阳县| 铜山县| 沁源县| 沧源| 商南县| 乌海市| 土默特左旗| 双城市| 静海县| 六枝特区| 凤山市| 林周县| 乾安县| 舟曲县| 盐津县| 丹阳市| 南充市| 通道| 高唐县| 甘谷县| 龙门县| 武陟县| 仪征市| 镇安县| 藁城市| 淄博市| 贺州市| 辉县市| 盐边县| 略阳县| 博湖县| 永定县| 监利县| 望谟县|