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的方法時,就是空的。java

分析一波

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

  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;">

相關文章
相關標籤/搜索