SpringBoot加載配置文件的幾種方式


首先回憶一下在沒有使用SpringBoot之前也就是傳統的spring項目中是如何讀取配置文件,通過I/O流讀取指定路徑的配置文件,然后再去獲取指定的配置信息。

傳統項目讀取配置方式

  • 讀取xml配置文件
    public String readFromXml(String xmlPath, String property) {
        SAXReader reader = new SAXReader();
        Document doc = null;
        try {
            doc = reader.read(new File(xmlPath));
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        Iterator<Element> iterator = doc.getRootElement().elementIterator();
        while (iterator.hasNext()){
            Element element = iterator.next();
            if (element.getQName().getName().equals(property)){
                return element.getTextTrim();
            }
        }
        return null;
    }
  • 讀取.properties配置文件
  public String readFromProperty(String filePath, String property) {
        Properties prop = new Properties();
        try {
            prop.load(new FileInputStream(filePath));
            String value = prop.getProperty(property);
            if (value != null) {
                return value;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

SpringBoot讀取配置方式

如何使用SpringBoot讀取配置文件,從使用Spring慢慢演變,但是本質原理是一樣的,只是SpringBoot簡化配置,通過注解簡化開發,接下來介紹一些常用注解。

@ImportResource注解

  • 這個注解用來導入Spring的配置文件,是配置文件中的內容注入到配置類中,參數是一個數組,可以注入多個配置文件
  • 代碼演示:
    在SpringBoot項目的resources目錄下創建一個xml配置文件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="configBean" class="com.example.test.config.ConfigBean">
        <property name="dbType" value="Oracle"/>
        <property name="driverClassName" value="jdbc.driver.Oracle.OracleDriver"/>
        <property name="host" value="127.0.0.1"/>
        <property name="userName" value="oracle"/>
        <property name="password" value="oracle"/>
    </bean>
</beans>

創建配置類ConfigBean

package com.example.test.config;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * @author Vincente
 * @date 2020/07/12-12:29
 * @desc 配置類
 **/
@Setter
@Getter
@ToString
public class ConfigBean {
    private String dbType;
    private String driverClassName;
    private String host;
    private String userName;
    private String password;
}

添加@ImportResource注解,在SpringBoot項目的啟動類添加

package com.example.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

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

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

測試代碼

package com.example.test;

import com.example.test.config.ConfigBean;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith(SpringRunner.class)

class TestApplicationTests {
    @Autowired
    private ConfigBean configBean;
    @Test
    void testConfigBean(){
        System.out.println(configBean);
    }
}

輸出結果

ConfigBean(dbType=Oracle, driverClassName=jdbc.driver.Oracle.OracleDriver, host=127.0.0.1, userName=oracle, password=oracle)
  • 小結 @ImportResource注解可以用來加載一個外部xml文件,注入到項目完成配置,但是這樣引入xml並沒有達到SpringBoot簡化配置的目的。

@Configuration和@Bean注解

  • @Configuration和@Bean注解並不能讀取配置文件中的信息,但是這兩個類本身用來定義配置類

@Configuration用來代替xml文件,添加在一個類上面
@Bean用來代替bean標簽,聲明在方法上,方法的返回值返回一個對象到Spring的IoC容器中,方法名稱相當於bean標簽中的ID

  • 代碼樣例
    聲明一個bean
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Vincente
 * @date 2020/07/12-13:28
 * @desc
 **/
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplateConfig restTemplate(){
        return new RestTemplate();
    }
}

測試代碼

package com.example.test;

import com.example.test.config.RestTemplateConfig;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@SpringBootTest
@RunWith(SpringRunner.class)

class TestApplicationTests {
    @Resource
    private RestTemplateConfig restTemplate;

    @Test
    void testConfigBean(){
        System.out.println(restTemplate);
    }
}

輸出結果

com.example.test.config.RestTemplateConfig@de7e193

@Import注解

  • @Import注解是用來導入配置類或者一些需要前置加載的類,帶有@Configuration的配置類(4.2 版本之前只可以導入配置類,4.2版本之后 也可以導入 普通類)
  • 代碼樣例
    結合上面的代碼做修改,不全部貼出
    將RestTemplateConfigestTemplateConfig類中的@Configuration注解去掉,在ConfigBean中導入
@Setter
@Getter
@ToString
@Import(RestTemplateConfig.class)
public class ConfigBean {
    private String dbType;
    private String driverClassName;
    private String host;
    private String userName;
    private String password;
}

測試代碼

package com.example.test;

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@SpringBootTest
@RunWith(SpringRunner.class)

class TestApplicationTests {
    @Resource
    ApplicationContext ctx;

    @Test
    void testConfigBean(){
        System.out.println(ctx.getBean("restTemplate"));
    }
}

輸出結果

com.example.test.config.RestTemplateConfig@6cd15072
  • 小結 可以看到在IoC容器中已經導入了RestTemplateConfig(普通)類,這個注解類似於之前applicationContext.xml中的import標簽

@ConfigurationProperties和@Value

  • @ConfigurationProperties和@Value這兩個注解算是在SpringBoot中用的比較多的注解了,可以在項目的配置文件application.yml和application.properties中直接讀取配置,但是在用法上二者也是有一定的區別
  • 代碼樣例
    創建配置文件application.yml
db-config:
  db-type: Oracle
  driver-class-name: jdbc.driver.Ooracle.OracleDriver
  host: 127.0.0.1
  user-name: Oracle
  password: Oracle

server:
  port: 8080

創建配置類ConfigBean

package com.example.test.config;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author Vincente
 * @date 2020/07/12-12:29
 * @desc 配置類
 **/
@Setter
@Getter
@ToString
@ConfigurationProperties(prefix = "db-config")
public class ConfigBean {
    private String dbType;
    private String driverClassName;
    private String host;
    private String userName;
    private String password;
}

測試代碼

package com.example.test;

import com.example.test.config.ConfigBean;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@SpringBootTest
@RunWith(SpringRunner.class)

class TestApplicationTests {
    @Resource
    ConfigBean configBean;
    @Value("${server.port}")
    private String port;

    @Test
    void testConfigBean(){
        System.out.println(configBean);
        System.out.println(port);
    }
}

輸出結果

ConfigBean(dbType=Oracle, driverClassName=jdbc.driver.Ooracle.OracleDriver, host=127.0.0.1, userName=Oracle, password=Oracle)
8080
  • 總結 二者的一些區別
特性 @ConfigurationProperties @Value
SpEL表達式 不支持 支持
屬性松散綁定 支持 不支持
JSR303數據校驗 支持 不支持

JSR303校驗演示:

添加校驗注解

package com.example.test.config;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.Null;

/**
 * @author Vincente
 * @date 2020/07/12-12:29
 * @desc 配置類
 **/
@Setter
@Getter
@ToString
@ConfigurationProperties(prefix = "db-config")
@Validated
public class ConfigBean {
    @Null
    private String dbType;
    private String driverClassName;
    private String host;
    private String userName;
    private String password;
}

輸出結果

Description:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'db-config' to com.example.test.config.ConfigBean failed:

    Property: db-config.dbType
    Value: Oracle
    Origin: class path resource [application.yml]:2:12
    Reason: 必須為null

@PropertySource注解

  • @ConfigurationProperties和@Value這兩個注解默認從項目的主配置文件中讀取配置,當項目配置較多全部從一個地方讀取會顯得臃腫,可以將配置文件按照模塊拆分讀取到不同的配置類中,可以使用@PropertySource配合@Value讀取其他配置文件
  • 代碼樣例
    創建配置文件db-config.yml
/**
 * @author Vincente
 * @date 2020/07/12-14:19
 * @desc
 **/
db-config:
  db-type: Oracle
  driver-class-name: jdbc.driver.Ooracle.OracleDriver
  host: 127.0.0.1
  user-name: Oracle
  password: Oracle

創建配置類ConfigBean

package com.example.test.config;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * @author Vincente
 * @date 2020/07/12-12:29
 * @desc 配置類
 **/
@Setter
@Getter
@ToString
@PropertySource("classpath:db-config.yml")
@Component
public class ConfigBean {
    @Value("${db-type}")
    private String dbType;
    @Value("${driver-class-name}")
    private String driverClassName;
    @Value("${host}")
    private String host;
    @Value("${user-name}")
    private String userName;
    @Value("${password}")
    private String password;
}

測試代碼

package com.example.test;

import com.example.test.config.ConfigBean;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@SpringBootTest
@RunWith(SpringRunner.class)

class TestApplicationTests {
    @Resource
    ConfigBean configBean;

    @Test
    void testConfigBean(){
        System.out.println(configBean);
    }
}

輸出結果

ConfigBean(dbType=Oracle, driverClassName=jdbc.driver.Ooracle.OracleDriver, host=127.0.0.1, userName=Vincente, password=Oracle)
  • 小結
    @PropertySource 用於獲取類路徑下的db-config.yml配置文件,@Value用於獲取yml中的配置信息,@Component注解用來將配置類交給Spring容器管理

總結

SpringBoot中提供了注解代替配置文件的方式來獲取項目中的配置,大大簡化了開發,以上總結了常用的讀取配置的方法,簡單來說就是兩種文件(yml和properties)幾大注解(@Value,@PropertySource,@Configuration,@ConfigurationProperties,@Import,@Bean);首先要了解每個注解的使用場景后,其次根據項目實際情況來具體的使用


免責聲明!

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



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