spring IOC加載流程

看了網上、書上不少對於spring IOC容器加載過程的分析。大多都只是粗略的講一下加載流程。其實這樣也不錯,簡單粗暴。清晰記得以前和一個前輩交流時他說的一句話:什麼設計模式、設計框架都是扯淡,能實現這個功能就是最好的。其實這樣的說法是話走偏鋒的,爲何要有各類框架、設計模式,主要仍是由於沒有它們不可以很好的實現功能。就好比說IOC容器加載中經常使用的FileSystemXmlApplicationContext,這個類到最頂層的BeanFactory接口,之間有8層集成實現關係。爲何只須要一個類行進工做,缺是存在了這麼多的集成實現關係呢?實際上是爲了更好的拓展和兼容,爲了更好的解耦。對於這些源碼的閱讀分析,若是隻是在停留在看懂了實現流程的地步上,不會有太多的收穫。
 
 
1、spring的整體框架:
     
 
一、spring的三個主要的部分,beans、context、core:
    在這三個主要部分中的核心是什麼呢?那就非beans莫屬了。spring的核心就是把咱們平時使用的對象配置文件化,而配置文件中的對象就是被解析爲beans來供開發人員來使用的。要說一個spring是一個舞臺劇,那麼beans就是一個個演員,沒有演員怎麼來的舞臺劇?bean在spring中的重要性可想而知。而context的做用就是封裝一下beans。若是沒有context的話,咱們每次使用spring的編程模式就必定要使用編程式使用spring的ioc容器了,而有了context只有,使用spring的ioc容器變得簡單了許多,可使用聲明式的方式了。那麼core的做用是什麼呢?其實core就是一個工具類,若是咱們想要將其更名爲utils其實都是能夠的。
 
 
二、beans:·
 
   BeanFactory是全部的bean工廠的父接口,bean工廠的繼承實現關係非常錯綜複雜,其中的一條主線繼承關係就以下圖所示。BeanFactory中定義getBean()等基本方法。而HierachicalBeanFactrory主要是說明Bean工廠是能夠繼承實現的,因此其中定義了getParentBeanFactory()這個接口。而ConfigurableBeanFactory這個類就是咱們經常使用的bean工廠了。
    
 
 
三、context:
  ApplicationContext 是 Context 的頂級父類。以下圖:
 
 能夠看到Application實際上是繼承自BeanFactory的。其就是對於BeanFactory環境的一個更好的整合。有了BeanFactory咱們能夠進行編程式Ioc,那麼有了ApplicationContext以後咱們就可使用聲明式Ioc了,Context對於各類類型的配置文件的兼容整合大大提高了使用者的使用效率。
Context 做爲 Spring 的 Ioc 容器,基本上整合了 Spring 的大部分功能,或者說是大部分功能的基礎。
 
 
 
2、容器加載流程:
 
   一、首先看FileSystemApplicationContext這個context容器的使用過程當中內部都作了什麼:
         a、 能夠看到FileSystemApplicationContext的類繼承關係以下圖所示:
      
 
 
        
    FileSystemApplicationContext之上還有AbstractApplicationContext抽象類等等,如此設計的緣由就是爲了靈活性、解耦的緣由。AbstractApplicationContext中增長了context容器相對於beanFactory容器新增長的特性功能,以後AbstractXmlApplicationContext又增長了對於xml配置文件解析的一些特性方法。每一層繼承實現的類,都是實現了職責功能的單一性。目前我接觸到的類繼承設計形式大部分都是一個接口、一個抽象類、一個實現類。若是考慮到拓展性和解耦兼容的話,就要實現多層繼承,每一層有多個實現類,就好比AbstractXmlApplicationContet這一層,就有多個實現,有xml配置文件解析功能類,有web數據解析的功能類,等等。每一層的每一個實現類都劃分出單一職責。
 
     b、FileSystemXmlApplicationContext解析xml配置文件載入IOC容器:
          
         流程圖以下:
 
 
    
   能夠看到,真正對於配置文件的解析是在BeanDefinitionParserDelegate類中的parseBeanDefinitionElement方法來實現的。其中該方法的代碼以下:
     
/**
* Parse the bean definition itself, without regard to name or aliases. May return
* {@code null} if problems occurred during the parsing of the bean definition.
*/
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, BeanDefinition containingBean) {

this.parseState.push(new BeanEntry(beanName));

String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}

try {
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
AbstractBeanDefinition bd = createBeanDefinition(className, parent);

parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

parseMetaElements(ele, bd);
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

parseConstructorArgElements(ele, bd);
parsePropertyElements(ele, bd);
parseQualifierElements(ele, bd);

bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));

return bd;
}
catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
}
catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
}
catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
}
finally {
this.parseState.pop();
}

return null;
}
    (1)解析:能夠看到parsePropertyElements()等方法就是對於配置文件中property屬性的解析。解析到的元素放置在AbstractBeanDefinition中,而AbstractBeanDefinition由BeanDefinitionHolder來持有。
 
    (2)註冊:獲得瞭解析信息要怎麼來使用呢,從咱們平時根據beanName經過getBean()來獲取到指定對象的方式,能夠看到應該是由一個HashMap來持有的配置文件信息。因此接下來spring IOC作的事就是把解析獲得的BeanDefinitionHolder中的信息註冊到一個HashMap中去。註冊是怎麼作的呢?
  在DefaultBeanDefinitionDocumentReader中調用BeanDefinitionReaderUtils中的registerBeanDefinition()方法,最終是使用了DefaultListableBeanFactory這個BeanFactory工廠來最總實現了註冊。
   (3)使用:最後就是如何使用了:經過getBean()方法來調用使用。
 
4、算了~~  原本還想繼續詳細寫的,我認慫了~~  真的好費事!!!  有空繼續補充吧。
相關文章
相關標籤/搜索