spring源碼之IOC的非核心部分
阿新 • • 發佈:2018-08-09
構造方法 置配 finish 總結 clas lec lose ica XML
前言
這篇是對IOC的非核心部分進行分析,是除去了初始化和依賴註入的部分進行分析。對於非web應用,我們在使用spring時,我們會new一個上下文,比如常用的new ClassPathXmlApplicaionContext("applicationContext.xml")。
那麽我們就從這句開始進行分析。
概述
源碼分析
- 從new 開始,這裏我們可以看到,做了下面幾個事情
- 構造方法委托處理,設置父類上下文,這裏我們可以看到設置為null,即沒有父上下文
- 設置配置文件路徑,解析設置的路徑放到configLocations中就好
- 判斷是否需要刷新上下文,這裏refresh=true,所以會刷新上下文
//ClassPathXmlApplicationContext類的方法 public ClassPathXmlApplicationContext(String... configLocations) throws BeansException { this(configLocations, true, null); } //ClassPathXmlApplicationContext類的方法 public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } } //AbstractRefreshableConfigApplicationContext類的方法 //設置資源文件路徑 public void setConfigLocations(String... locations) { if (locations != null) { Assert.noNullElements(locations,"Config locations must not be null"); this.configLocations = new String[locations.length]; for (int i = 0; i < locations.length; i++) { this.configLocations[i] = resolvePath(locations[i]).trim(); } } else { this.configLocations = null; } }
- 總入口,刷新上下文
//AbstractApplicationContext類方法 //刷新上下文,模板模式,我們可以通過實現這個抽象類,實現自己的applicationContext public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //為上下文刷新做準備 prepareRefresh(); //獲取bean工廠,完成bean定義的註冊,這裏核心後面分析 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //對上面創建好的bean工廠做預處理 prepareBeanFactory(beanFactory); try { //對bean工廠進行後置處理 postProcessBeanFactory(beanFactory); //調用bean工廠的後置處理器 invokeBeanFactoryPostProcessors(beanFactory); //註冊bean的後置處理器 registerBeanPostProcessors(beanFactory); //初始化消息源 initMessageSource(); //初始化事件廣播器 initApplicationEventMulticaster(); //初始化一些特殊的bean onRefresh(); //註冊監聽 registerListeners(); //初始化所有非懶加載的單例 finishBeanFactoryInitialization(beanFactory); //發布合適的事件 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } //銷毀單例bean destroyBeans(); //取消刷新 cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring‘s core, since we // might not ever need metadata for singleton beans anymore... //釋放緩存 resetCommonCaches(); } } }
-
為上下文刷新做準備,這裏主要做了幾件事件
- 設置容器處理激活狀態
- 初始和校驗屬性源,在spring mvc的AbstractRefreshableWebApplicationContext有到
- 初始一個早期事件的空鏈表
//AbstractApplicationContext類的方法 //為上下文刷新做準備 protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // Initialize any placeholder property sources in the context environment initPropertySources(); // Validate that all properties marked as required are resolvable // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>(); }
- 獲取bean工廠
核心後面進行分析
- bean工廠的預處理
總結
Aware接口的很簡單,但很實用
參考鏈接
https://www.cnblogs.com/niejunlei/archive/2016/11/11/6054713.html(prepareBeanFactory)
spring源碼之IOC的非核心部分