Spring Boot下自定義配置屬性的讀取

一.應用場景
    使用Spring Boot開發,經常需要自定義配置屬性,例如系統全局屬性,或者外部調用的常量屬性等,那麼這些配置屬性應該放在哪裏比較合適?怎麼讀取並在代碼中使用呢?

二. 屬性配置
    在Spring Boot中,有兩種常用的配置文件格式:properties和yml。下面總結了幾種常見的屬性配置和讀取方式:

  1. 直接使用JDK自帶的 java.util.ResourceBundle
    JDK本身提供了 java.util.ResourceBundle 工具類可以用於讀取properties配置文件。
    在這裏插入圖片描述
package com.hong.util;

import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 * @author wanghong
 * @date 2019/06/14 22:48
 * properties屬性文件讀取器
 **/
public class PropertiesReader {

    private ResourceBundle resourceBundle;

    public PropertiesReader(String propertiesHolder) {
        this.resourceBundle = ResourceBundle.getBundle(propertiesHolder, Locale.getDefault());
    }

    public String getLabel(String key) {
        String label;
        try {
            label = new String(resourceBundle.getString(key).getBytes("ISO-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        return label;
    }
}
package com.hong.config;

import com.hong.util.PropertiesReader;

/**
 * @author wanghong
 * @date 2019/06/14 22:49
 * App端屬性配置常量類,綁定到類路徑下app_config.properties資源
 **/
public class AppConfig {
    private static PropertiesReader getPropertiesVal = new PropertiesReader("app_config");

    public static final String MY_PROP = getPropertiesVal.getLabel("myProp");
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class ConfigTest {
   @Test
   public void testConfig(){
       System.out.println(AppConfig.MY_PROP); //123456
   }
}
  1. @ConfigurationProperties
    在這裏插入圖片描述
package com.hong.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author wanghong
 * @date 2019/06/14 23:08
 **/
@Data
@Component
@ConfigurationProperties(prefix = "app")
public class AppConfig2 {
   private String version;
}
package com.hong.controller;

import com.hong.config.AppConfig2;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author wanghong
 * @date 2019/06/14 23:14
 **/
@Api(value = "測試控制器")
@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private AppConfig2 appConfig2;

    @ApiOperation(value = "屬性讀取測試")
    @RequestMapping(value = "testConfig",method = RequestMethod.GET)
    public String testConfig() {
        String version = appConfig2.getVersion();
        return version;
    }
}

在這裏插入圖片描述

如果現在 application-dev.yml中也定義了該屬性:
在這裏插入圖片描述
且 spring.profiles.active=dev,那麼讀取到的 version = 1.0.0

  1. @PropertySource
    現在再來看另一種場景: 假如我在 app_config.properties中也定義了該屬性:
    在這裏插入圖片描述
    如何讓 AppConfig2中讀取的值是該文件中配置的值呢?這時就要手動指定屬性源了。
package com.hong.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * @author wanghong
 * @date 2019/06/14 23:08
 **/
@Data
@Component
@PropertySource(value = { "classpath:app_config.properties" }, encoding = "UTF-8")
@ConfigurationProperties(prefix = "app")
public class AppConfig2 {
   private String version;
}

但這裏有一個坑,我本機Spring Boot使用的版本是2.0.4.RELEASE,如果在Spring Boot默認的全局屬性文件application.yml或application.properties或application-{profile}.yml或application-{profile}.properties中存在與自定義屬性配置文件中同名的屬性,那麼即使加了@PropertySource(value = { “classpath:app_config.properties” }, encoding = “UTF-8”)也不管用,最終讀取到的還是默認全局屬性文件中的值,當然一般出現這種情況,就是命名衝突的問題了,注意下就行了。

還有一種場景即使同一個屬性值在不同的profile環境中值是不同的,如app_config.properties在dev環境下是1.1.0,在prod下是1.2.0,這時我們可以在resources目錄下分別創建dev和prod兩個文件夾,放置app_config.properties,然後設置下 @PropertySource的文件路徑。
在這裏插入圖片描述
在這裏插入圖片描述
當然這種情況就是需要做到環境隔離了,如果是微服務的話,可以結合Spring Cloud使用分佈式配置中心服務,將不同環境的配置放到git中方便修改和統一管理。

  1. @Value
package com.hong.config;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * @author wanghong
 * @date 2019/06/15 0:36
 **/
@Data
@Component
@PropertySource("classpath:app_config.properties")
public class AppConfig3 {
    @Value("${app.version}")
    private String version;
}
  1. @ConfigurationProperties與@Value的區別
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章