日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Spring IoC(二)IoC容器的初始化过程

發(fā)布時(shí)間:2024/9/30 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring IoC(二)IoC容器的初始化过程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

(一)IoC 容器初始化過(guò)程概述

1.1簡(jiǎn)要概述初始化過(guò)程

IoC 容器的初始化過(guò)程是通過(guò)refresh() 方法來(lái)啟動(dòng)的,這個(gè)方法標(biāo)識(shí)著IoC 容器正式啟動(dòng)。具體來(lái)說(shuō),這個(gè)啟動(dòng)過(guò)程包括:BeanDefinition 的Resource 定位、載入和注冊(cè)三個(gè)基本過(guò)程。

Spring 把這三個(gè)過(guò)程分開,并使用不同的模塊來(lái)完成,通過(guò)這樣的設(shè)計(jì)方式,可以讓用戶更加靈活的對(duì)這三個(gè)過(guò)程進(jìn)行裁剪或擴(kuò)展,從而方便自己定義IoC 容器的初始化過(guò)程。

第一個(gè)過(guò)程是Resource 的定位過(guò)程。這個(gè)Resource 的定位指的是BeanDefinition 的資源定位,它由ResourceLoader 通過(guò)統(tǒng)一的Resource 接口來(lái)完成。對(duì)于BeanDefinition 的存在形式,可以是文件系統(tǒng)中的,通過(guò)FileSystemResource 來(lái)進(jìn)行抽象;類路徑中定義的Bean 信息可以通過(guò)ClassPathResource 來(lái)進(jìn)行抽象。等等。這個(gè)過(guò)程可以理解為IoC 容器尋找數(shù)據(jù)的過(guò)程。

第二個(gè)過(guò)程是BeanDefinition 的載入。這個(gè)載入過(guò)程是把用戶定義好的Bean 定義成IoC 容器內(nèi)部的數(shù)據(jù)結(jié)構(gòu),而這個(gè)容器內(nèi)部數(shù)據(jù)結(jié)構(gòu)就是BeanDefinition。具體來(lái)說(shuō),這個(gè)BeanDefinition 實(shí)際上就是POJO 對(duì)象在IoC 容器中的抽象,通過(guò)這個(gè)BeanDefinition 定義的數(shù)據(jù)結(jié)構(gòu),使IoC 容器能夠方便地管理Bean。

第三個(gè)過(guò)程是向IoC 容器中注冊(cè)這些BeanDefinition 的過(guò)程。這個(gè)過(guò)程是通過(guò)BeanDefinitionRegistry 接口的實(shí)現(xiàn)來(lái)完成的。這個(gè)注冊(cè)過(guò)程把載入過(guò)程中解析得到的BeanDefinition 向IoC 容器進(jìn)行注冊(cè)。在IoC 容器內(nèi)部將BeanDefinition 注入到一個(gè)HashMap 中去,IoC 容器就是通過(guò)這個(gè)HashMap 來(lái)持有這些Bean 數(shù)據(jù)的。

這里談的IoC 容器的初始化過(guò)程,并不包含Bean 依賴注入的實(shí)現(xiàn)。在Spring IoC 的設(shè)計(jì)中,Bean 定義的載入和依賴注入是兩個(gè)獨(dú)立的過(guò)程。依賴注入一般發(fā)生在第一個(gè)通過(guò)getBean() 向容器中獲取Bean 的時(shí)候。但是也并不全是這樣,比如我們對(duì)某個(gè)Bean 設(shè)置了lazyinit 屬性,那么Bean 的依賴注入在其初始化的過(guò)程中就已經(jīng)完成了。

(二)IoC 容器具體初始化過(guò)程解析

2.1BeanDefinition 的Resource 定位

ApplicationContext 是一個(gè)接口,其實(shí)現(xiàn)類主要有:FileSystemXmlApplicationContext、
ClassPathXmlApplicationContext 和XmlWebApplicationContext 等。從這些類的名字就可以分析的出其加載文件的位置。FileSystemXmlApplicationContext 可以從文件系統(tǒng)中載入Resource、ClassPathXmlApplicationContext 可以從類路徑下載入Resource、XmlWebApplicationContext 可以從Web 容器中載入Resource。

這里以FileSystemXmlApplicationContext 為例,來(lái)分析ApplicationContext 的實(shí)現(xiàn)是如何完成Resource 定位的,下面是這個(gè)類對(duì)應(yīng)的繼承體系。

下面是更為詳細(xì)的繼承體系。

從上圖中可以看出FileSystemXmlApplicationContext 已經(jīng)通過(guò)繼承AbstractApplicationContext 具備了ResourceLoader 的功能,因?yàn)锳bstractApplicationContext 繼承自DefaultResourceLoader。下面是其源代碼:

public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext {public FileSystemXmlApplicationContext() {}public FileSystemXmlApplicationContext(ApplicationContext parent) {super(parent);}/*** * @param configLocation 表示BeanDefinition 所在的文件路徑* @throws BeansException*/public FileSystemXmlApplicationContext(String configLocation) throws BeansException {this(new String[] {configLocation}, true, null);}/*** * @param configLocations 表示BeanDefinition 文件數(shù)組所在的路徑* @throws BeansException*/public FileSystemXmlApplicationContext(String... configLocations) throws BeansException {this(configLocations, true, null);}/*** * @param configLocations 可以包含多個(gè)BeanDefinition 的文件路徑* @param parent 指定自己的IoC 雙親容器* @throws BeansException*/public FileSystemXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {this(configLocations, true, parent);}/*** * @param configLocations 文件數(shù)組* @param refresh 是否自動(dòng)刷新上下文* @throws BeansException*/public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {this(configLocations, refresh, null);}public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)throws BeansException {super(parent);setConfigLocations(configLocations);if (refresh) {refresh();}}/*** 文件系統(tǒng)中Resource 的實(shí)現(xiàn),通過(guò)一個(gè)FileSystemResource 來(lái)得到一個(gè)在文件系統(tǒng)中定位的BeanDefinition* @param path 文件路徑* @return*/@Overrideprotected Resource getResourceByPath(String path) {if (path != null && path.startsWith("/")) {path = path.substring(1);}return new FileSystemResource(path);}}

對(duì)BeanDefinition 資源定位的過(guò)程,最初是由refresh() 方法觸發(fā)的,refresh() 方法的調(diào)用是在
FileSystemXmlApplicationContext 的構(gòu)造函數(shù)中啟動(dòng)的。getResourceByPath() 方法的調(diào)用過(guò)程主要如下:

從上面的源代碼中可以看出,只要是以XML 文件方式存在的BeanDefinition 都能夠得到有效的處理。上面的源代碼中并沒(méi)有涉及到BeanDefinition 的信息讀入,那么FileSystemXmlApplicationContext 是怎么完成信息的讀入的呢?
上面已經(jīng)提到過(guò)BeanDefinition 資源的定位、載入和注冊(cè)過(guò)程都是分開進(jìn)行的。關(guān)于這個(gè)讀入器的配置,可以在FileSystemXmlApplicationContext 的基類AbstractRefreshableApplicationContext 中查看。

這里主要看AbstractRefreshableApplicationContext 中的refreshBeanFactory() 方法的實(shí)現(xiàn),
這個(gè)方法被FileSystemXmlApplicationContext 構(gòu)造函數(shù)中的refresh() 方法所調(diào)用。在refreshBeanFactory()這個(gè)方法中,通過(guò)createBeanFactory() 創(chuàng)建一個(gè)IoC 容器供AppliCationContext 使用。這個(gè)IoC 容器就是上一篇博文中提到的DefaultListableBeanFactory。同時(shí),還啟動(dòng)了loadBeanDefinitions() 來(lái)載入BeanDefinition。下面是refreshBeanFactory() 的方法的源碼:

@Overrideprotected final void refreshBeanFactory() throws BeansException {// 如果已經(jīng)建立了BeanFactory,則銷毀并關(guān)閉if (hasBeanFactory()) {destroyBeans();closeBeanFactory();}try {// 通過(guò)createBeanFactory() 方法獲得一個(gè)創(chuàng)建的IoC 容器// 創(chuàng)建的是DefaultListableBeanFactory 容器DefaultListableBeanFactory beanFactory = createBeanFactory();beanFactory.setSerializationId(getId());customizeBeanFactory(beanFactory);// 載入BeanDefinitionloadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}}

在BeanDefinition 定位完成的基礎(chǔ)上,就可以通過(guò)返回的Resource 對(duì)象來(lái)進(jìn)行BeanDefinition 的載入了。在完成定位過(guò)程后,為BeanDefinition 的載入創(chuàng)造了I/O 操作的條件,但是具體的數(shù)據(jù)還沒(méi)有開始讀入。

2.2BeanDefinition 的載入和解析

先發(fā)出來(lái),慢慢更!

總結(jié)

以上是生活随笔為你收集整理的Spring IoC(二)IoC容器的初始化过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。