Spring IOC容器的設(shè)計(jì):
第一條設(shè)計(jì)路徑:
從接口BeaFactory--->HierarchicalBeanFaxtory--->ConfigurableBeanFactory是一條主要的BeanFactory設(shè)計(jì)路徑辩诞。
BeanFactory:定義了容器基本的功能算利,就好像水桶能裝水一樣燥撞。
HierarchicalBeanFaxtory:增加了BeanFactory的方法觉啊,如增加了getParentBeanFactory()方法
ConfigurableBeanFactory:定義了一些BeanFactory的配置功能嘉抒。
第二條設(shè)計(jì)路徑:
從BeanFactory--->ListableBeanFactory--->ApplicationContext--->WebApplicationContext或者ConfigurableApplicationContext是以ApplicationContext為核心的接口設(shè)計(jì)姿鸿。
ListableBeabFactory:細(xì)化了BeanFactory接口的許多方法殖卑。
對(duì)于ApplicationiContext接口站削,他通過(guò)繼承MessageSource,ResourceLoader孵稽,ApplicationEventPublisher接口许起,在BeanFactory的簡(jiǎn)單IOC容器的基礎(chǔ)上添加了許多對(duì)高級(jí)容器的特性支持。
這里涉及是主要的接口系統(tǒng)菩鲜,而具體的容器都是在該接口系統(tǒng)下實(shí)現(xiàn)的园细。如DefaultListableBeanFactory就實(shí)現(xiàn)了ConfigrableBeanFactory。
BeanFactory應(yīng)用場(chǎng)景:
1接校、區(qū)分BeanFactory和FactoryBean:
BeanFactory是一個(gè)Factory猛频,也就是容器或?qū)ο蠊S,在Spring中蛛勉,所有的Bean都是由BeanFactory來(lái)進(jìn)行管理的鹿寻。FactoryBean是一個(gè)Bean,這個(gè)Bean不是一個(gè)簡(jiǎn)單的Bean诽凌,而是一個(gè)能產(chǎn)生或修飾對(duì)象生成的工廠Bean
2毡熏、BeanFactory定義了容器的基本方法,如:
通過(guò)接口方法containsBean讓用戶(hù)判斷容器中是否有指定名字的Bean
通過(guò)isSingleton方法來(lái)查詢(xún)制定名字的Bean是否是Singleton類(lèi)型的Bean
........
3侣诵、BeanFactory的設(shè)計(jì)原理:(以XmlBeanFactory容器為例)
XmlBeanFactory繼承了DefaultListableBeanFactory痢法,從而具有容器的重要基本功能狱窘。通過(guò)名字就可以猜到,XmlBeanFactory是一個(gè)與Xml相關(guān)的BeanFactory财搁,也就是說(shuō)蘸炸,他是一個(gè)可以讀取以XML方式定義的BeanDefinition的IOC容器。在XmlBeanFactory中妇拯,初始化了一個(gè)XmlBeanDefinitionReader,通過(guò)這個(gè)Reade對(duì)象來(lái)讀取以Xml方式定義的BeanDefinition幻馁。但是,首先要將這些BeanDefinition封裝成Resource類(lèi)來(lái)給出越锈,Resource類(lèi)是Spring用來(lái)封裝I/O操作的類(lèi)。然后將Resource類(lèi)作為構(gòu)造參數(shù)傳遞給XmlBeanFactory膘滨。在構(gòu)造函數(shù)中通過(guò)XmlBeanDefinitionReader的loadBeanDenfinitions(resources)來(lái)加載Bean甘凭。詳細(xì)請(qǐng)看XmlBeanFactory源碼。
ClassPathResource res = new ClassPathResource("bean.xml");
DefaultListableBeanFactory? factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(res);
這樣火邓,我們就通過(guò)factory對(duì)象來(lái)使用DefautListableBeanFactory這個(gè)IOC容器丹弱,在使用容器時(shí),需要如下幾個(gè)步驟:
1铲咨、創(chuàng)建IOC配置文件的抽象資源躲胳,這個(gè)抽象資源包括了BeanDefinition的定義信息。
2纤勒、創(chuàng)建一個(gè)BeanFactory坯苹,這里使用DefauleListableBeanFactory。
3摇天、創(chuàng)建一個(gè)BeanDefinition讀取器粹湃,這里使用XmlBeanDefinitionReader來(lái)載入XML文件形式的Beanfinition,通過(guò)一個(gè)回調(diào)配置給BeanFactory泉坐。
4为鳄、從定義好的資源位置讀取配置信息,具體的解析過(guò)程由XmlBeanDefinitionReader來(lái)完成腕让。完成整個(gè)載入和注冊(cè)過(guò)程之后孤钦,這個(gè)容器就創(chuàng)建起來(lái)了。
ApplicationContext的應(yīng)用場(chǎng)景:
1纯丸、Application簡(jiǎn)單介紹
ApplicationContext是一個(gè)高級(jí)形態(tài)的IOC容器偏形,在BeanFactory的基礎(chǔ)上添加了附加功能,這些功能液南,為ApplicationContext提供了BeanFactory不具有的新特性壳猜。
-支持不同的信息源。ApplicationContext擴(kuò)展了MessageSource接口滑凉,這些信息源的擴(kuò)展功能可以支持國(guó)際化的實(shí)現(xiàn)统扳,為開(kāi)發(fā)多語(yǔ)言版本的應(yīng)用提供服務(wù)喘帚。
-訪(fǎng)問(wèn)信息。這一特性體現(xiàn)在對(duì)ResourceLoader和Resource的支持上咒钟,這樣我們可以從不同的地方得到Bean定義資源吹由,尤其是從不同I/O途徑得到Bean定義信息。具體來(lái)說(shuō)朱嘴,ApplicationContext都是繼承了DefaultResourceLoader倾鲫。DefaultResourceLoader是AbstractApplicationContext的基類(lèi)。
-支持應(yīng)用事件萍嬉。繼承了接口ApplicationEventPublisher乌昔,從而在上下文中引入了事件機(jī)制。這些時(shí)間和Bean的生命周期的結(jié)合俄日Bean的管理提供了便利壤追。
-在ApplicationContext中提供了附加服務(wù)磕道,使得ApplicationContext與簡(jiǎn)單的BeanFactory相比,對(duì)他的使用是一種面向框架的使用風(fēng)格行冰,所以一般建議在開(kāi)發(fā)應(yīng)用中使用ApplicationContext作為IOC容器的基本形式溺蕉。
2、ApplicationContext設(shè)計(jì)原理原理(以FileSystemXmlApplicationContext為例)
在FileSystemXmlApplicationContext的設(shè)計(jì)中悼做,其主要的功能已經(jīng)在它的基類(lèi)AbstractXmlApplicationContext中已經(jīng)實(shí)現(xiàn)疯特,在FileSystemXmlApplicationContext中只需要實(shí)現(xiàn)和他自身設(shè)計(jì)相關(guān)的兩個(gè)功能。
第一個(gè)功能是肛走,如果應(yīng)用直接使用FileSystemXmlApplicationContext漓雅,對(duì)于實(shí)例化這個(gè)應(yīng)用上下文的支持,同時(shí)啟動(dòng)IOC容器的refresh()的過(guò)程羹与。在FileSystemXmlApplicationContext的代碼中可以看到故硅,代碼如下:
public FileSystemXmlApplicationContext(String[] configLocations,boolean refresh,ApplicationContext parent) throws BeanException {
super(parent) ;
setConfigLocations(configLocations);
id(refresh){
refresh();
}
}
這個(gè)refresh()過(guò)程會(huì)牽扯到IOC容器啟動(dòng)的一系列復(fù)雜操作,同時(shí)纵搁,對(duì)于不同的容器實(shí)現(xiàn)吃衅,這些操作都是類(lèi)似的。
第二個(gè)功能是與FileSystemXmlApplicationContext設(shè)計(jì)具體相關(guān)的功能腾誉,這部分與怎樣從文件系統(tǒng)中記載XML的Bean定義資源有關(guān)徘层。通過(guò)這個(gè)過(guò)程,可以為在文件系統(tǒng)中讀取以XMl形式存在的BeanDefinition做準(zhǔn)備利职,不同的應(yīng)用上下文對(duì)應(yīng)著不同的讀取Bean Definition的方式趣效,在FileSystemXmlApplicationContext中實(shí)現(xiàn)的代碼如下:
protected Resource getResourceByPath(String path){
if(path != null && path.startsWith("/")){
path = path.substring(1);
}
return new FileSystemResource(path);
}