使用工具類,靜態讀取配置檔案中的配置的寫法
@Component
public class ConfigUtils {
private static ConfigUtils instance;//單例模式持有當前工具類的例項
private ConfigUtils(){}
@Value("${system.uploadPath}")
private String uploadPath;//@Value註解讀取配置,為類物件的屬性
@Value("${basicLog}")
private String basicLog;
@PostConstruct//在建立類物件後,執行一些操作
public void init(){
instance = this;//將IOC容器自動建立的工具類的bean例項物件,配置為單例持有的物件
}
public static String getUploaderRootPath(){//提供獲取配置的靜態方法
return instance.uploadPath;
}
public static String getBasicLog(){
return instance.basicLog;
}
}
如果是單體架構的專案,上面的程式碼,已經能夠實現了,無外乎就是多設定幾個屬性,或者屬性很多的話,使用@ConfigurationProperties(prefix = "xxx"),的方式,統一賦值,減少手寫@Value註解。
注意,微服務架構的話,以上寫法,可能會導致一個問題,就是這些配置,可能會存在滯後性。因為上述程式碼,本質是Spring掃描到ConfigUtils類的@Component註解,並生成物件時,@Value註解,從配置檔案中,讀取配置,並設定屬性。在物件建立完畢,依賴注入完畢後,執行到@PostConstruct修飾的init初始化方法時,將IOC容器中的ConfigUtils物件,賦給instance。但是,當在微服務架構中,在配置中心,修改配置檔案,並開啟了動態重新整理功能,雖然動態重新整理,可以重新整理到環境Environment,但是卻無法修改,最初IOC容器中的this物件,這也就導致,看似重新整理了配置中心中的配置,但是使用ConfigUtils.getUploaderRootPath()方法,獲取到的配置,依舊是,應用啟動時,讀取到的舊的配置。
問題是,如何在保證在配置中心的配置檔案修改後,能夠保證使用ConfigUtils獲取到最新的配置呢?
1.要麼就是,每次配置檔案重新整理後,都將配置重新重新整理到配置類的屬性上。
這個很難實現,因為無法控制,什麼時候重新整理,以及重新整理那些類的屬性。也可能是我的技術水平,不高,所以對這一條解決方法,沒有思路。
2.要麼就是,每次獲取屬性時,都獲取最新的(每次獲取配置時,都使用Environment進行獲取)。
public class ConfigUtils {
private static Environment environment;
private ConfigUtils(){}
// private String uploadPath;
//
// private String basicLog;
public static void init(Environment env){
environment = env;
}
public static String getUploaderRootPath(){
return environment.getProperty("upload_path");
}
public static String getBasicLog(){
return environment.getProperty("basicLog");
}
}
但是上面程式碼,很明顯是錯誤的,因為沒有為environment賦值,什麼時候,賦值呢?當然是配置檔案中的配置都寫入到Environment存放在IOC容器中之後,鑑於配置寫入完成時,沒有一個標誌。可以使用應用啟動完成後,再進行賦值,此時肯定寫入完成了。主啟動類實現CommandLineRunner介面,重寫run(String... args)方法,在其中定義應用啟動完成後,執行後續的一些操作。
@...(註解省略了)
public class XxxApplication implements CommandLineRunner { #org.springframework.boot.CommandLineRunner
@Resource
private Environment environment;
public static void main(String[] args) {
SpringApplication.run(XxxApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
ConfigUtils.init(environment);
}
}
這樣,就能保證,動態重新整理後,使用ConfigUtils獲取配置,獲取到最新的。
只是為了記錄自己的學習歷程,且本人水平有限,不對之處,請指正。