java 靜態代碼塊和spring @value等注解注入順序


java 靜態代碼塊和spring @value等注解注入順序

問題所在

先上代碼

java方法

@Value("${mf.cashost}")
public static String casHost;

public static String getCasHost() {
    if (StringUtils.isEmpty(casHost)) {
  //casHost = "http://sso.abc.com.cn/sso/";
        casHost = "http://ssotest.abc.com.cn/sso/";
    }
    return casHost;
}

配置文件

mf.cashost=http://sso.abc.com.cn/sso/

正常我們想要的getCasHost的值,肯定是sso.abc.com.cn,而不是ssotest,但是如果調用getCasHost肯定是返回test的,或者說,casHost最開始進到getCasHost的方法時,就是空的。

分析一波

關於實例變量與構造方法的初始化順序問題

  1. Java類會先執行構造方法,然后再給注解了@Value 的屬性注入值,所以在執行靜態代碼塊的時候,就會為null。
  2. Java 及Spring 初始化順序:java靜態屬性/靜態代碼塊(根據聲明的先后順序加載)、構造代碼塊、 構造方法(即:spring創建FetchStockSchedule的實例 交給Spring 管理)、@Value/@ AutoWired/@Resouce 等注解 的成員變量等賦值。

解決一下

解決方案

  1. 首先,讓當前類變成Spring的bean,
  2. 再使用@PostConstruct
@Value("${mf.cashost}")
private String mfCasHost;

private static String casHost;

@PostConstruct
public void init() {
    casHost = mfCasHost;
}

public static String getCasHost() {
    if (StringUtils.isEmpty(casHost)) {
        casHost = "http://ssotest.abc.com.cn/sso/";
    }
    return casHost;
}

原理

Java中該注解的說明:
@PostConstruct該注解被用來修飾一個非靜態的void()方法。被@PostConstruct修飾的方法會在服務器加載Servlet的時候運行,並且只會被服務器執行一次。PostConstruct在構造函數之后執行,init()方法之前執行。

通常我們會是在Spring框架中使用到@PostConstruct注解 該注解的方法在整個Bean初始化中的執行順序:
此時的執行順序:

  1. 構造方法
  2. Before Initialization
  3. 使用PostConstruct注解
  4. InitializingBean接口
  5. init-method指定的初始化方法
  6. After Initialization

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">


免責聲明!

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



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