Spring 系列目錄(http://www.javashuo.com/article/p-kqecupyl-bm.html)html
本節介紹容器初始化的第一步:環境準備工做。java
prepareRefresh 函數主要是作些準備工做,例如對系統屬性及環境變量的初始化及驗證。spring
protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); // 1. 留給子類覆蓋,如添加要驗證的屬性 initPropertySources(); // 2. 驗證須要的屬性文件是否都已經放入環境中 getEnvironment().validateRequiredProperties(); // 3. 若是多播器還未初始化完成,就將早期發佈的事件統一放到集合中,等多播器初始化完成後再發布事件 this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>(); }
網上有人說其實這個函數沒什麼用,由於最後兩句代碼纔是最爲關鍵的,可是卻沒有什麼邏輯處理,initPropertySources 是空的,沒有任何邏輯,而 getEnvironment().validateRequiredProperties() 也由於沒有須要驗證的屬性而沒有作任何處理。其實這這都是由於沒有完全理解纔會這麼說,這個函數若是用好了做用仍是挺大的。那麼,該怎麼用呢?咱們先探索下各個函數的做用。app
(1) initPropertySources 正符合 Spring 的開放式結構設計,給用戶最大擴展 Spring 的能力。用戶能夠根據自身的須要重寫 initPropertySources 方法,並在方法中進行個性化的屬性處理及設置。ide
(2) validateRequiredProperties 則是對屬性進行驗證,那麼如何驗證呢?咱們舉個融合兩句代碼的小例子來幫助你們理解。函數
假如如今有這樣一個需求,工程在運行過程當中用到的某個設置(例如 VAR)是從系統環境變量中取得的,而若是用戶沒有在系統環境變量中配置這個參數,那麼工程可能不會工做。這一要求可能會有各類各樣的解決辦法,固然,在 Spring 中能夠這樣作,你能夠直接修改 Spring 的源碼,例如修改 ClassPathXmlApplicationContext。固然,最好的辦法仍是對源碼進行擴展,咱們能夠自定義類:ui
public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext { public MyClassPathXmlApplicationContext(String configLocations) throws BeansException { super(configLocations); } public MyClassPathXmlApplicationContext(String path, Class<?> clazz) throws BeansException { super(path, clazz); } @Override protected void initPropertySources() { // 添加驗證要求 getEnvironment().setRequiredProperties("VAR"); } }
咱們自定義了繼承自 ClassPathXmlApplicationContext 的 MyClassPathXmlApplicationContext,並重寫了 initPropertySources 方法,在方法中添加了咱們的個性化需求,那麼在驗證的時候也就是程序走到 getEnvironment().validateRequiredProperties() 代碼的時候,若是系統並無檢測到對應 VAR 的環境變量,那麼將拋出異常。固然咱們還須要在使用的時候替換掉原有的this
public static void main(String[] args) { ApplicationContext context = new MyClassPathXmlApplicationContext( "spring-context-test.xml", Main.class); MyTestBean myTestBean = (MyTestBean) context.getBean("myTestBean"); }
天天用心記錄一點點。內容也許不重要,但習慣很重要!設計