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

詳解Spring中的Environment外部化配置管理

 更新時(shí)間:2022年02月21日 11:00:20   作者:跟著Mic學(xué)架構(gòu)  
本文主要介紹了Spring中的Environment外部化配置管理,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

Environment的中文意思是環(huán)境,它表示整個(gè)spring應(yīng)用運(yùn)行時(shí)的環(huán)境信息,它包含兩個(gè)關(guān)鍵因素

  • profiles
  • properties

profiles

profiles這個(gè)概念相信大家都已經(jīng)理解了,最常見的就是不同環(huán)境下,決定當(dāng)前spring容器中的不同配置上下文的解決方案。比如針對(duì)開發(fā)環(huán)境、測(cè)試環(huán)境、生產(chǎn)環(huán)境,構(gòu)建不同的application.properties配置項(xiàng),這個(gè)時(shí)候我們可以通過profiles這個(gè)屬性來決定當(dāng)前spring應(yīng)用上下文中生效的配置項(xiàng)。

實(shí)際上,通過profiles可以針對(duì)bean的配置進(jìn)行邏輯分組。 簡(jiǎn)單來說,我們可以通過profiles來針對(duì)不同的bean進(jìn)行邏輯分組,這個(gè)分組和bean本身的定義沒有任何關(guān)系,無論是xml還是注解方式,都可以配置bean屬于哪一個(gè)profile分組。

當(dāng)存在多個(gè)profile分組時(shí),我們可以指定哪一個(gè)profile生效,當(dāng)然如果不指定,spring會(huì)根據(jù)默認(rèn)的profile去執(zhí)行。我們來通過一個(gè)代碼演示一下。

ProfileService

創(chuàng)建一個(gè)普通的類,代碼如下

public class ProfileService {
    private String profile;

    public ProfileService(String profile) {

        this.profile = profile;
    }

    @Override
    public String toString() {
        return "ProfileService{" +
                "profile='" + profile + '\'' +
                '}';
    }
}

聲明一個(gè)配置類

在配置類中,構(gòu)建兩個(gè)bean,配置不同的profile。

@Configuration
public class ProfileConfiguration {

    @Bean
    @Profile("dev")
    public ProfileService profileServiceDev(){
        return new ProfileService("dev");
    }

    @Bean
    @Profile("prod")
    public ProfileService profileServiceProd(){
        return new ProfileService("prod");
    }
}

定義測(cè)試方法

public class ProfileMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext();
//        applicationContext.getEnvironment().setActiveProfiles("prod");
        applicationContext.register(ProfileConfiguration.class);
        applicationContext.refresh();
        System.out.println(applicationContext.getBean(ProfileService.class));
    }
}

可以通過很多種方式來激活配置,默認(rèn)情況下不添加applicationContext.getEnvironment().setActiveProfiles("prod");時(shí),會(huì)發(fā)現(xiàn)bean沒有被裝載。添加了之后,會(huì)根據(jù)當(dāng)前激活的profiles來決定裝載哪個(gè)bean。

除此之外,我們還可以在啟動(dòng)參數(shù)中增加-Dspring.profiles.active=prod來決定當(dāng)前激活哪個(gè)profile。該屬性可以配置在系統(tǒng)環(huán)境變量、JVM系統(tǒng)屬性、等。

注意配置文件不是單選;可能會(huì)同時(shí)激活多個(gè)配置文件,編程式的使用方法setActiveProfiles(),該方法接收String數(shù)組參數(shù),也就是多個(gè)配置文件名

applicationContext.getEnvironment().setActiveProfiles("prod","dev");

如果沒有任何profile配置被激活,默認(rèn)的profile將會(huì)激活。 默認(rèn)profile配置文件可以更改,通過環(huán)境變量的setDefaultProfiles方法,或者是聲明的spring.profiles.default屬性值

profiles總結(jié)

簡(jiǎn)單總結(jié)一下profiles,通過profiles可以最一組bean進(jìn)行邏輯分組,這些邏輯分組的bean會(huì)根據(jù)Environment上下文中配置的激活的profile來進(jìn)行加載,也就是Environment對(duì)于profiles配置來說,它能決定當(dāng)前激活的是哪個(gè)profile配置。

  • 一個(gè)profile就是一組Bean定義的邏輯分組。
  • 這個(gè)分組,也就 這個(gè)profile,被賦予一個(gè)命名,就是這個(gè)profile名字。
  • 只有當(dāng)一個(gè)profile處于active狀態(tài)時(shí),它對(duì)應(yīng)的邏輯上組織在一起的這些Bean定義才會(huì)被注冊(cè)到容器中。
  • Bean添加到profile可以通過XML定義方式或者annotation注解方式。
  • Environment對(duì)于profile所扮演的角色是用來指定哪些profile是當(dāng)前活躍的缺省。

Properties

properties的作用就是用來存放屬性的,它可以幫我們管理各種配置信息。這個(gè)配置的來源可以是properties文件、JVM properties、系統(tǒng)環(huán)境變量、或者專門的Properties對(duì)象等。

我們來看一下Environment這個(gè)接口,它繼承了PropertyResolver,這個(gè)接口和屬性的操作有關(guān),也就是我們可以通過Environment來設(shè)置和獲得相關(guān)屬性。

public interface Environment extends PropertyResolver {
    String[] getActiveProfiles();

    String[] getDefaultProfiles();

    /** @deprecated */
    @Deprecated
    boolean acceptsProfiles(String... var1);

    boolean acceptsProfiles(Profiles var1);
}

至此,我們可以可以簡(jiǎn)單的總結(jié)Environment的作用,Environment提供了不同的profile配置,而PropertyResolver提供了配置的操作,由此我們可以知道,Spring 容器可以根據(jù)不同的profile來獲取不同的配置信息,從而實(shí)現(xiàn)Spring容器中運(yùn)行時(shí)環(huán)境的處理。

environment的應(yīng)用

在spring boot應(yīng)用中,修改application.properties配置

env=default

創(chuàng)建一個(gè)Controller進(jìn)行測(cè)試

@RestController
public class EnvironementController {

    @Autowired
    Environment environment;

    @GetMapping("/env")
    public String env(){
        return environment.getProperty("env");
    }
}

指定profile屬性

在前面的內(nèi)容中我們介紹了profile和property這兩個(gè)概念,現(xiàn)在我們來結(jié)合使用加深對(duì)這兩者的理解。

在spring boot應(yīng)用中,默認(rèn)的外部化配置是application.properties文件,事實(shí)上,除了這個(gè)默認(rèn)的配置文件之外,我們還可以使用springboot中的約定命名格式來實(shí)現(xiàn)不同環(huán)境的配置

application-profile.properties

當(dāng)前spring boot應(yīng)用選擇使用哪個(gè)properties文件作為上下文環(huán)境配置,取決與當(dāng)前激活的profile。同樣,我們可以通過很多種方式來激活,比如在application.properties中增加spring.profiles.active=dev這種方式,也可以在JVM參數(shù)中增加該配置來指定生效的配置。

在不指定的情況下,則使用默認(rèn)的配置文件,簡(jiǎn)單來說,如果沒有顯式激活某一個(gè)配置文件,那么應(yīng)用程序就將加載application-default.properties中的屬性。

這個(gè)功能非常實(shí)用,一般的公司里面都會(huì)有幾套運(yùn)行環(huán)境,比如開發(fā)、測(cè)試、生產(chǎn)環(huán)境,這些環(huán)境中會(huì)有一些配置信息是不同的,比如服務(wù)器地址。那我們需要針對(duì)不同的環(huán)境使用指定的配置信息,通過這種方式就可以很方便的去解決。

@Value注解的使用

在properties文件中定義的屬性,除了可以通過environment的getProperty方法獲取之外,spring還提供了@Value注解,

@RestController
public class EnvironementController {

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

    @GetMapping("/env")
    public String env(){
        return env;
    }
}

spring容器在加載一個(gè)bean時(shí),當(dāng)發(fā)現(xiàn)這個(gè)Bean中有@Value注解時(shí),那么它可以從Environment中將屬性值進(jìn)行注入,如果Environment中沒有這個(gè)屬性,則會(huì)報(bào)錯(cuò)。

Spring Environment原理設(shè)計(jì)

結(jié)合前面咱們講過的內(nèi)容,我們來推測(cè)一下Environment的實(shí)現(xiàn)原理。

簡(jiǎn)單演示一下Environment中的配置來源

  • @Value("${java.version}") 獲取System.getProperties , 獲取系統(tǒng)屬性
  • 配置command的jvm參數(shù), -Denvtest=command

基于現(xiàn)有的內(nèi)容的推導(dǎo),我們可以畫出下面這樣一個(gè)圖。

image-20211216204620415

  • 第一部分是屬性定義,這個(gè)屬性定義可以來自于很多地方,比如application.properties、或者系統(tǒng)環(huán)境變量等。
  • 然后根據(jù)約定的方式去指定路徑或者指定范圍去加載這些配置,保存到內(nèi)存中。
  • 最后,我們可以根據(jù)指定的key從緩存中去查找這個(gè)值。

下面這個(gè)是表示Environment的類關(guān)系圖,這個(gè)類關(guān)系圖還是非常清晰的體現(xiàn)了Environment的原理。

image-20211216210040646

上述類圖的核心API說明如下

Environment接口,繼承了PropertyResolver。 PropertyResolver,它主要有兩個(gè)作用。

  • 通過propertyName屬性名獲取與之對(duì)應(yīng)的propertValue屬性值(getProperty)。
  • ${propertyName:defaultValue}格式的屬性占位符,替換為實(shí)際的值(resolvePlaceholders)。

PropertyResolver的具體實(shí)現(xiàn)類是PropertySourcesPropertyResolver,屬性源的解決方案。該類是體系中唯一的完整實(shí)現(xiàn)類。它以PropertySources屬性源集合(內(nèi)部持有屬性源列表List )為屬性值的來源,按序遍歷每個(gè)PropertySource,獲取到一個(gè)非null的屬性值則返回。

其中,PropertySourcesPropertyResolver中的List ,表示不同屬性源的來源,它的類關(guān)系圖如下,表示針對(duì)不同數(shù)據(jù)源的存儲(chǔ)。

image-20211216211933822

 到此這篇關(guān)于詳解Spring中的Environment外部化配置管理的文章就介紹到這了,更多相關(guān)Spring Environment外部化配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • IntelliJ IDEA設(shè)置顯示內(nèi)存指示器和設(shè)置內(nèi)存大小的方法

    IntelliJ IDEA設(shè)置顯示內(nèi)存指示器和設(shè)置內(nèi)存大小的方法

    這篇文章主要介紹了IntelliJ IDEA設(shè)置顯示內(nèi)存指示器和設(shè)置內(nèi)存大小的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • java持久層框架mybatis防止sql注入的方法

    java持久層框架mybatis防止sql注入的方法

    下面小編就為大家?guī)硪黄猨ava持久層框架mybatis防止sql注入的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-10-10
  • java中的GC收集器詳情

    java中的GC收集器詳情

    這篇文章主要介紹了java中的GC收集器,GC(Garbage collection )指的是程序內(nèi)存管理分手動(dòng)和自動(dòng),手動(dòng)內(nèi)存管理,需要我們編程的時(shí)候顯式分配和釋放空間,但如果忘記釋放,會(huì)造成嚴(yán)重的內(nèi)存泄漏問題,下面文章內(nèi)容我們就來實(shí)例說明情況,需要的朋友可以參考一下
    2021-10-10
  • mybatis實(shí)現(xiàn)對(duì)數(shù)據(jù)的增刪查改實(shí)例詳解

    mybatis實(shí)現(xiàn)對(duì)數(shù)據(jù)的增刪查改實(shí)例詳解

    這篇文章主要介紹了mybatis實(shí)現(xiàn)對(duì)數(shù)據(jù)的增刪查改實(shí)例詳解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • Java8中Optional的使用方法詳解

    Java8中Optional的使用方法詳解

    這篇文章主要介紹了Java8中Optional的使用方法詳解,傳統(tǒng)的寫代碼方式經(jīng)常會(huì)遇到NullPointerException,這就需要我們?cè)诖a中經(jīng)常判空,而判空的寫法又會(huì)顯得很累贅,這里就可以用到Optional來簡(jiǎn)化代碼,需要的朋友可以參考下
    2024-01-01
  • SpringBoot?Schedule調(diào)度任務(wù)的動(dòng)態(tài)管理

    SpringBoot?Schedule調(diào)度任務(wù)的動(dòng)態(tài)管理

    Scheduled定時(shí)任務(wù)是Spring?boot自身提供的功能,所以不需要引入Maven依賴包,下面這篇文章主要給大家介紹了關(guān)于SpringBoot通過@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)以及問題解決的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • java多線程Thread的實(shí)現(xiàn)方法代碼詳解

    java多線程Thread的實(shí)現(xiàn)方法代碼詳解

    這篇文章主要介紹了java多線程Thread的實(shí)現(xiàn)方法代碼詳解,涉及start(),run(),stop(),interrupt(),isInterrupted(),join()和join(long millis)等方法的介紹,具有一定借鑒價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • SpringBoot中@ComponentScan的使用詳解

    SpringBoot中@ComponentScan的使用詳解

    這篇文章主要介紹了SpringBoot中@ComponentScan的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 閱讀EnumSet抽象類源碼

    閱讀EnumSet抽象類源碼

    這篇文章主要介紹了閱讀EnumSet抽象類源碼,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-12-12
  • 淺談線程通信wait,notify作用

    淺談線程通信wait,notify作用

    這篇文章主要介紹了淺談線程通信wait,notify作用,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2017-12-12

最新評(píng)論