1. 程式人生 > >Spring入門---Spring框架底層原理

Spring入門---Spring框架底層原理

面試問題相關---http://blog.csdn.net/guolin6315/article/details/6732993點選開啟連結

Spring可以維護各個bean(物件),並向其中注入屬性值。那麼,如果要把一個物件的引用注入另一個物件

呢?應該怎麼處理呢?

對於物件中的屬性來說,我們注入屬性的方式為:在配置檔案中使用property標籤。

  <property name="物件屬性名稱" >
          <value>要注入的內容</value>
  </property>
    那麼如果我們的類中有對另一個物件的引用呢?這個時候,其實類似於注入一個屬性,只是需要使用ref標籤進行注入:首先我們需要通過bean配置兩個類,我們分別給他們的id命名為:類1、類2。這時假如我們的需求是類1中包含有對類2的引用。也就是說,類2是類1的一個屬性。這時我們就需要將類2的物件注入到類1物件中。配置檔案中的寫法如下:
<bean id= "類1" class="類1的全路徑">
       <!--這裡的注入方法類似於上面的value注入,可以寫在一行也可以多行-->
        <property name="類2在類1中的屬性名" ref="類2">
</bean>
    <!--這裡的類2是物件名稱,再注入的時候ref中的值必須和bean 後面的Id完全一致-->
<bean id="類2" class="類2的全路徑">
</bean>
以上的做法是我們的spring管理各個物件和維護各個物件之間的關係。其中具體的執行原理是:
當ClassPathXmlApplicationContext("applicationContext.xml")這句話執行的時候,Spring
容器物件就建立。這個物件會讀取applicationContext.xml中配置的bean就會被建立,並且放入記憶體。
具體是依賴於我們的反射機制。
    就拿上面程式碼說:首先類1被建立,建立後,假設這個物件記憶體中的地址為:

123物件中對於物件二的引用為(???)。此時的記憶體如下:

    

然後類2被建立,這時候,類2在物件中的記憶體地址會賦值給類1中相應欄位的引用。具體來說:假設類2的地址為:456這時123物件中的那個對於

物件2的引用由(???)改為(456)完成類的依賴注入。此時記憶體如下:

    

其實,這些物件都存在與applicationContext物件的一個類似於HashMap的引用中。這也是我們為什麼要將applicationContext物件設定為單例的原因。

    那麼,spring是如何實現剛才的那些個呼叫呢?首先,通過dom4j將我們的配置檔案讀取,這時我們就可以解析到所有相關的類的全路徑了。

然後,它再利用反射機制通過如下程式碼完成類的例項化:類1=Class.forName("類1的全路徑")。這時,我們就得到了類1。(這也是為啥當我們的類的

全路徑寫錯了會導致出現classNotfind的錯誤。)

    當我們得到了類1以後,通過呼叫類1的set方法,將屬性給物件進行注入。而且,需要遵循首字母大寫的set規範。例如:我們的類中有個字

段的屬性為name那麼set方法必須寫成setName(name 的首字母要大寫)否則會報一個屬性找不到的錯誤:

1   public void setName(String name){ 
2              this.name= name; 
3   } 

  物件建立後,我們將我們的物件id和我們的物件實體地址,一起存入類似於HashMap的容器中,然後呢,我們是如何獲得我們需要的物件,然後

執行物件中的方法呢?我們通過getBean的方法,通過物件Id獲得物件的實體地址,得到物件,然後呼叫物件的方法,完成對方法的呼叫。