springboot原理實戰(6)--配置文件注入集合,動態注入,切換profile環境

目錄

本篇文章是上篇文章的補充,主要內容概要如下:
在這裏插入圖片描述

一、配置文件後綴的2種方式

配置文件有2種*.properties*.yml,可以單獨使用也可以混合使用(不過項目中不知道有沒這麼幹的).
application.properties

jdbc.username=root

application.yml

jdbc:
  username: hufanglei
  password: 123456

運行入口函數,測試下:

@SpringBootApplication
public class Demo3Application {

   public static void main(String[] args) {
       ConfigurableApplicationContext context = SpringApplication.run(Demo3Application.class, args);
       System.out.println(context.getEnvironment().getProperty("jdbc.username"));
       System.out.println(context.getEnvironment().getProperty("jdbc.password"));
    }

運行結果:
在這裏插入圖片描述
打印了yml的jdbc.password和properties的username。

結果說明:
1.這2個配置文件都生效了。
2.如果2個配置文件重名,properties的優先級高。都有jdbc.username但是顯示的是properties的。

二、配置文件屬性注入擴展:集合和數組

配置文件屬性可以寫數組或集合,現在我們展示用這2種方式接受並讀取出來屬性值:
application.properties

ds.hosts[0]=192.168.157.1
ds.hosts[1]=192.168.157.2
ds.hosts[2]=192.168.157.3

#ds.ports=8080,8081,8082 //這種寫法也可以
ds.ports[0]=8080
ds.ports[1]=8081
ds.ports[2]=8082
@Component
@ConfigurationProperties("ds")
public class TomcatProperties {
    private List<String> hosts = new ArrayList<>();
    private String[] ports;
    public List<String> getHosts() {
        return hosts;
    }
    public void setHosts(List<String> hosts) {
        this.hosts = hosts;
    }


    public String[] getPorts() {
        return ports;
    }

    public void setPorts(String[] ports) {
        this.ports = ports;
    }

    @Override
    public String toString() {
        return "TomcatProperties{" +
                "hosts=" + hosts +
                ", ports=" + Arrays.toString(ports) +
                '}';
    }
}

開始測試:

@SpringBootApplication
public class Demo3Application {

   public static void main(String[] args) {
       ConfigurableApplicationContext context = SpringApplication.run(Demo3Application.class, args);
       System.out.println(context.getBean(TomcatProperties.class));
       context.close();
   }

運行結果:
在這裏插入圖片描述

三、EnvironmentPostProcessor 動態加載配置文件

配置文件的屬性我們從上篇博客瞭解到可以使用@Value和Environment的getProperty方法獲取, 也可以通過@PropertySource編碼方式讀取。
其實如果還有一種方式:
可以動態的從不同的地方收集配置文件,加入到自己的項目中並獲取。這個就是通過EnvironmentPostProcessor接口。
使用和其他的後置處理器一樣,自己實現這個接口,加載就可以。

準備一個配置文件:D:/tmp/springboot.properties

springboot.name=springboot

寫自己的環境後置處理器:

@Component
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        try(InputStream input = new FileInputStream("D:/tmp/springboot.properties")) {
            Properties source = new Properties();
            source.load(input);
            PropertiesPropertySource propertySource = new PropertiesPropertySource("my", source);
            environment.getPropertySources().addLast(propertySource);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

如果想讓我們的自定義的後置處理器生效還需要做一步:
在這裏插入圖片描述
在resource下配置META-INF下配置後置器到spring.factoryries中。
org.springframework.boot.env.EnvironmentPostProcessor=com.springboot.demo3.MyEnvironmentPostProcessor
在這裏插入圖片描述

這樣外部的配置文件就注入進來了,我們測試下:

@SpringBootApplication
public class Demo3Application {

   public static void main(String[] args) {
       ConfigurableApplicationContext context = SpringApplication.run(Demo3Application.class, args);    
      System.out.println(context.getEnvironment().getProperty("springboot.name"));
       context.close();
   }

運行結果顯示已經打印:
在這裏插入圖片描述

四、指定多個profile

在開發時可能有多個環境,開發環境dev,測試環境test,默認環境default,生成環境prod,現在我們來切換和指定不同的環境。
準備三個配置文件:
application.properties

jdbc.url=mysql:jdbc;//127.0.0.1/db_springboot

application-dev.properties

jdbc.url=mysql:jdbc;//127.0.0.1/db_springboot_dev

application-test.properties

jdbc.url=mysql:jdbc;//127.0.0.1/db_springboot_test

①硬編碼編程方式:

主要是在入口函數中,硬編碼指定:

@SpringBootApplication
public class Demo3Application {

    public static void main(String[] args) {
        //編程的方式指定:生效的profie
        SpringApplication app = new SpringApplication(Demo3Application.class);
        app.setAdditionalProfiles("dev");
//        app.setAdditionalProfiles("test");
        ConfigurableApplicationContext context = app.run(args);
        System.out.println(context.getEnvironment().getProperty("jdbc.url"));
    }
}

運行:
在這裏插入圖片描述

@SpringBootApplication
public class Demo3Application {

    public static void main(String[] args) {
        //編程的方式指定:生效的profie
        SpringApplication app = new SpringApplication(Demo3Application.class);
//        app.setAdditionalProfiles("dev");
        app.setAdditionalProfiles("test");
        ConfigurableApplicationContext context = app.run(args);
        System.out.println(context.getEnvironment().getProperty("jdbc.url"));
    }
}

運行結果:
在這裏插入圖片描述

@SpringBootApplication
public class Demo3Application {

    public static void main(String[] args) {
        //編程的方式指定:生效的profie
        SpringApplication app = new SpringApplication(Demo3Application.class);
//        app.setAdditionalProfiles("dev");
//        app.setAdditionalProfiles("test");
        ConfigurableApplicationContext context = app.run(args);
        System.out.println(context.getEnvironment().getProperty("jdbc.url"));
    }
}

運行結果:
在這裏插入圖片描述
結果顯示,根據編碼方式切換了不同的配置文件
那在啓動的時候可以切換嗎?
可以的。可以在啓動時候添加參數,指定一個或者多個配置文件。

②參數方式:

在啓動參數中配置:

--spring.profiles.active=xx

在這裏插入圖片描述
運行結果,顯示一切換到test環境下。
在這裏插入圖片描述

bean注入的時候: 方法或者類上添加@Profile

某個類或者某個方法想要在指定的環境下執行,可以通過@Profile註解指定:
我們寫個配置類:

@SpringBootConfiguration
public class MyConfig {

    @Bean
    public Runnable createRunnable(){
        System.out.println("========1=====");
        return () -> {};
    }

    @Bean
    @Profile("test")
    public Runnable createRunnable2(){
        System.out.println("========2=====");
        return () -> {};
    }

    @Bean
    @Profile("dev")
    public Runnable createRunnable3(){
        System.out.println("========3=====");
        return () -> {};
    }
}

我們想要createRunnable方法在默認配置下執行(其實在所有的環境下都會觸發),createRunnable2在test環境下執行,createRunnable3在dev環境下執行,就可這樣定義:
結合上面的啓動參數,我們讓其生效:
在這裏插入圖片描述
觸發了默認和test方法:
在這裏插入圖片描述
指定多個文件:
在這裏插入圖片描述
啓動後運行結果:都觸發了。
在這裏插入圖片描述
我們也可以在類上指定一個@Profile,雖然沒有-prod配置文件,但是我們可以在類上這樣寫,只有啓動參數上加上纔可以觸發這個類的方法:

@SpringBootConfiguration
@Profile("prod")
public class MyConfig {

    @Bean
    public Runnable createRunnable(){
        System.out.println("========1=====");
        return () -> {};
    }

    @Bean
    public Runnable createRunnable2(){
        System.out.println("========2=====");
        return () -> {};
    }

    @Bean
    public Runnable createRunnable3(){
        System.out.println("========3=====");
        return () -> {};
    }
}

如果啓動參數不寫,不會打印這幾個方法,如下圖,空的啥也沒打印:
在這裏插入圖片描述
如果我們這樣配置了,就會出觸發這個類的所有方法:
在這裏插入圖片描述
再次運行:
在這裏插入圖片描述


個人微信公號:
搜索: 怒放de每一天
不定時推送相關文章,期待和大家一起成長!!
在這裏插入圖片描述


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章