SpringBoot中配置文件讀取


1.准備環境

有如下配置文件,yml格式和properties格式

yml格式(經我測試發現,屬性前面的空格兩個不行,需要四個空格才能讀出來,這應該是yml的語法,並且屬性:后面必須有一個空格):

person:
    name: 張三
    age: 18
    birth: 2020/10/1
    maps: {k1: v1,k2: v2}
    lists:
      - item1
      - item2
      - item3
    phone:
      os: ios
      model: iphone11
      price: 9999

properties格式:

person.name= 張三
person.age= 18
person.birth= 2020/10/1
person.maps.k1=  v1
person.maps.k2= v1
person.lists= item1,item2,item3
person.phone.os= ios
person.phone.model= iphone11
person.phone.price= 9999

建立與之對應的類,並實現getter、setter和toString

Person類

public class Person {
    private String name;
    private int age;
    private Date birth;
    private HashMap<String,Object> maps;
    private List<Object> lists;
    private Phone phone;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", phone=" + phone +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public HashMap<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(HashMap<String, Object> maps) {
        this.maps = maps;
    }

    public List<Object> getLists() {
        return lists;
    }

    public void setLists(List<Object> lists) {
        this.lists = lists;
    }

    public Phone getPhone() {
        return phone;
    }


    public void setPhone(Phone phone) {
        this.phone = phone;
    }
}

Phone類型:

public class Phone {
    private String os;
    private String model;
    private double price;

    @Override
    public String toString() {
        return "Phone{" +
                "os='" + os + '\'' +
                ", model='" + model + '\'' +
                ", price=" + price +
                '}';
    }

    public String getOs() {
        return os;
    }

    public void setOs(String os) {
        this.os = os;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

2.使用@ConfigurationProperties獲取配置文件

在Person類上面寫注解:@ConfigurationProperties、@Component

@Component: 通過添加 @Component 注解讓 Component Scan 掃描到
@ConfigurationProperties(prefix = "person"): # perfix表示通過指定的前綴,綁定配置文件中的配置

@Component   
@ConfigurationProperties(prefix = "person")   # perfix表示
public class Person {
}
這里配置完成后idea會有一個小提示:未配置 Spring Boot 配置注釋處理器,此時我們可以將如下配置寫入pom文件的dependencies中
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-configuration-processor</artifactId>
      <optional>true</optional>
</dependency>
然后重新生成pom文件運行項目,就可以在配置文件中提示出我們定義的Person類

測試是否配置成功

我們在測試類中進行測試
@SpringBootTest
class ConfigurationDemoApplicationTests {

    @Autowired
    private Person person;
    @Test
    void contextLoads() {
        System.out.println(person);
    }
}
運行測試會在控制台中打印出,表示已經配置成功
Person{name='張三', age=18, birth=Thu Oct 01 00:00:00 CST 2020, maps={k1=v1, k2=v2}, lists=[item1, item2, item3], phone=Phone{os='ios', model='iphone11', price=9999.0}}

如果我們使用的配置文件是properties,中文會出現亂碼,如何解決?

打開idea,將透明的原生到 ASCII 轉換勾選上就可以了

3.使用@Value注解獲取配置文件

有如下配置:

@Component
public class Person {
    @Value("${person.name}")
    private String name;
    @Value("#{10*2}")
    private int age;
    @Value("1999/1/1")
    private Date birth;
    private HashMap<String,Object> maps;
    private List<Object> lists;
    private Phone phone;
}
測試結果:
Person{name='張三', age=20, birth=Fri Jan 01 00:00:00 CST 1999, maps=null, lists=null, phone=null}

4.@ConfigurationProperties 和 @Value 獲取值比較

@ConfigurationProperties @Value
功能 批量注入配置文件的屬性 單獨指定
松散綁定 支持 不支持
SpEL 不支持 支持
JSR303數據校驗 支持 不支持
復雜類型(map、list) 支持 不支持
松散綁定:

比如綁定person.firstName,配置文件中可以寫:person.firstName、person.first-name、person.first_name、PERSON_FIRST_NAME

SpEL:

#{10*10} 數學計算
#{10>1?"是":"否"} 比較運算
#{field.toString()} 調用方法
#{T(java.lang.Math).PI} 調用靜態方法

JSR303數據校驗:

必須使用@ConfigurationProperties

@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
    @Email
    private String name;
}

@Value相對來說更加靈活,有如下情況,我們只需要person.name

@Value("${person.name}")
private String personName;
@RequestMapping("/hello")
public String index(){
    return "hello"+personName;
}

訪問 /hello 可以返回:hello張三

5. 加載指定的配置文件 @PropertySource

有時候我們並不想把某些配置放在全局的配置文件下,比如我們將person配置放在 resource 目錄下:

person.properties
person.name= 李四
person.age= 30
person.birth= 2020/10/1
person.maps.k1=  v1
person.maps.k2= v1
person.lists= item1,item2,item3
person.phone.os= ios
person.phone.model= iphone12
person.phone.price= 11111

那么應該如何讀取呢?在配置類上新增:@PropertySource(value = {"classpath:person.properties"})

@Component
@ConfigurationProperties(prefix = "person")
@PropertySource(value = {"classpath:person.properties"})
public class Person {
}

運行測試,控制台打印如下:

Person{name='李四', age=30, birth=Thu Oct 01 00:00:00 CST 2020, maps={k1=v1, k2=v1}, lists=[item1, item2, item3], phone=Phone{os='ios', model='iphone12', price=11111.0}}

6. 通過@ImportResource實現xml配置的裝載,導入Spring的配置文件,讓配置文件里的內容生效

@ImportResource:導入Spring的配置文件,讓配置文件里面的內容生效;SpringBoot所有的bean裝載全部通過java配置實現,那么一直以來習慣的xml配置是否就沒有了用武之地呢,答案是否定的

在項目中增加一個services/HelloService類

在resource目錄下增加一個配置文件

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="helloService"  class="com.qingtian.configurationdemo.services.HelloService"></bean>
</beans>

編寫單元測試方法

@Autowired
ApplicationContext context;

@Test
public void testHelloService(){
    System.out.println(context.containsBean("helloService"));
}

運行單元測試,控制台打印是:false

SpringBoot中沒有Spring的配置文件,而且我們自己寫的配置文件,也不能自動識別,如何讓配置文件生效呢?

@ImportResource(locations = {"classpath:beans.xml"})
public class ConfigurationDemoApplication {
}

再次運行測試方法,控制台打印:true

SpringBoot不推薦編寫xml配置文件,更推薦使用全注解的方式

編寫我們的配置類 config/MyConfig

@Configuration  //指明當前類是一個配置類,就是來代替之前的Spring的配置文件
public class MyConfig {

    //將方法的返回值添加到容器中,容器默認的id就是方法名
    @Bean
    public HelloService helloService(){
        return new HelloService();
    }
}

7.配置文件中的占位符

RandomValuePropertiSource:配置文件中可以使用隨機數

${random.value} ${random.int} ${random.long} ${random.int(10)} ${random.int[1024,65535]}

屬性配置占位符

app.name=myapp
app.description=${app.name} is a Spring Boot application

-- 可以在配置文件中引用前面配置過的屬性
-- ${app.name:默認值}來指定找不到屬性時的默認值

8.通過Profile配置SpringBoot項目的不同環境

當我們需要在開發、測試、生產系統不斷切換時,如果只有一個配置文件,那會相當的麻煩,使用Profile對不同環境提供不同配置功能,可以通過激活、指定參數等方式快速切換環境

多profile文件形式:

--格式:application-{profile}.properties

  • application-dev.properties
  • application-prod.properties

多profile文檔塊模式(yml文件支持):

server:
  port: 8000
spring:
  profiles:
    active: dev
---
server:
  port: 8001
spring:
  profiles: dev
---
server:
  port: 80
spring:
  profiles: prod

激活方式:

  • 命令行 --spring.profiles.active=dev
  • 配置文件 spring.profiles.active=dev
  • jvm參數 -Dspring.profiles.active=dev

9.配置文件的加載位置

  • SpringBoot啟動會掃描以下位置的application.properties或application.yml文件作為SpringBoot的默認配置文件
    • file: ./config/
    • file: ./
    • classpath: /config/
    • classpath: /
    • 以上是按照 優先級從高到低的順序,所有位置的文件都會被加載,高優先級配置內容會覆蓋低優先級配置內容
    • 我們也可以通過配置spring.config.location來改變默認配置

10.外部配置加載順序

SpringBoot支持多種外部配置方式(優先級由高到低)

  • 命令行參數
  • 來自java:com/env的JNDI屬性
  • Java系統屬性(System.getProperties())
  • 操作系統環境變量
  • RandomValuePropertySource配置的random.*屬性值
  • jar包外部的application-{profile}.properties或application.yml(帶spring.profile)配置文件
  • jar包內部的application-{profile}.properties或application.yml(帶spring.profile)配置文件
  • jar包外部的application.properties或application.yml(不帶spring.profile)配置文件
  • jar包內部的application.properties或application.yml(不帶spring.profile)配置文件
  • @Configuration注解類上的@PropertySource
  • 通過SpringApplication.setDefaultProperties指定的默認屬性


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM