2015-11-10 72 views
0

我有一個對象叫做ApplicationProperties。該對象具有私有字段和公共getter方法。非常微不足道。如何僅在設置了對象的屬性後加載Spring Bean?

if (properties == null) { 
     properties = new ApplicationProperties(); 
     SettingsLoader settingsLoader = new SettingsLoader(properties); 
     settingsLoader.loadApplicationSettings(); 
    } 
    return properties; 

我也有春天豆類,其中一些依賴於ApplicationProperties閱讀一些路徑等,這對於長時間工作的罰款。 JDK是Oracle JDK 1.6。但是最近當我部署在OpenJDK 1.7 ICEDTEA 中時,我得到了一些NullPointerException,因爲spring bean使用的應用程序屬性具有空字段(未完全初始化)。

可能是平行類加載是在Open JDK的情況下完成的(不確定它)。

我該如何確保在ApplicationProperties完全準備好後才能實例化所有彈簧豆(數量超過200個 - 通過批註中的許多)?

回答

0

將屬性對象作爲構造函數依賴項注入到所有需要它的bean。

+0

實際上一些bean具有使用一些非bean類(使用應用程序屬性)設置的靜態字段。這是複雜的事情。 – phoenix

+0

有沒有其他方法?謝謝。 – phoenix

0

ApplicationProperties這個類是一個不受Spring IoC控制的非bean。由於某些原因,在Oracle JDK 1.6及更高版本上工作正常的代碼,但在Open JDK 1.7 ICEDTEA上無法運行,而且我得到了一些NullPointerException

僅供參考我將解決方案作爲答案發布。

由於在創建bean之前需要完全加載非bean類的屬性,所以我將加載部分委託給一個單獨的線程,並且對我來說工作得很好。

public class SettingsLoader implements Runnable { 
    //Other methods go here 
    @Override 
    public void run() { 
     loadApplicationSettings(); 
    } 
} 

而且的ApplicationProperties

private ApplicationProperties() { 
     SettingsLoader settingsLoader = new SettingsLoader(this); 
     Thread loader = new Thread(settingsLoader); 
     loader.setName("Settings Loader"); 
     logger.info("Settings Loader is initiated. Loading application settings."); 
     loader.setPriority(Thread.MAX_PRIORITY); 
     try { 
      loader.start(); 
      loader.join(); 
     } catch (InterruptedException ex) { 
      logger.error("Application settings loader is interrupted. Exception is", ex); 
     } 
    } 

有了這個當前線程等待,直到線程loader在構造函數中所做的設置應用程序性能領域的工作。