引子
系列1 - bean 標籤解析:
5、xml組態檔解析之【自定義】名稱空間【標籤】的解析.md
系列2 - bean 獲取: getBean() 做了什麼
說到 spring 是個學 java的人都能說上兩嗓子,人均三板斧不過分吧。
兩年前我走馬觀花一樣的過了一遍 spring 原始碼,自以為已經漸漸上道了。實際上過了兩年到了今天,忘了太多太多東西了,所以只好再拿起來看看。
先進入第一個專題, spring-bean.xml 的解析
到了如今,各種好用、便捷的註解已經漫天飛了,相信幾乎不會再有新專案通過這種方式開發了,但是我覺得如果真的需要深入理解spring的原始碼,我們再去仔細揣摩這個載入過程,想必也會有所得。
正所謂,萬變不離其宗,雖然通過一系列註解簡化了太多太多的設定,但是我覺得我們從最初的樣子,往往更能從本質上去理解他。
可能格式不一定對,我從原始碼包裡拷了一個過來改了一下當作案例
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class XmlBeanFactoryTest {
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("bean.xml"));
Object object = beanFactory.getBean("action");
}
上述就是 spring 最原始的使用方式了,我想只要路徑、名稱空間設定對了,執行起來問題不大。
別看方法體內只有兩行程式碼:
為了講清楚這兩行程式碼背後發生了什麼,我們後邊將會分成多個章節,進行敘述。
【相信我絕對是萬惡之源了】
正式進入文章分析之前,我們不妨大膽的猜想一下,假如由我們自己來實現,spring 的容器功能,那我們要怎麼做呢?
我們先問一個問題:java是物件導向的語言,那麼物件怎麼來的?當然不是相親相出來的物件。
以前寫過一篇部落格,物件的來源就如圖中這麼幾種:
地址:
克隆和序列化都不是無中生有的方案,所以我們暫且忽略
那麼剩下如下的方式可以無中生有:
前文的例子中,我們也沒有顯式的建立我們在bean.xml 中定義的物件,所以是反射。
再看 bean.xml 中定義的 bean的class 屬性,這不妥妥的類路徑麼?
總結一下,那麼我們可以猜測 spring 原始碼中可能會包含如下的元件:
更進一步,如果要保證單例,那麼勢必會有一個bean的全域性快取等等,"工廠" 這不他就悄悄的來了。
spring 原始碼中大量的用到了 "工廠模式"
如果懂代理的童鞋,應該知道一個叫做動態代理的東西,CGLIB 你可識得?面向切面程式設計,這不他就來了?
在解析bean的時候,我們完全可以通過動態代理(為原類生成子類),附加一些行為上去,比如方法的攔截實現:
想必你也會注意到這麼一個問題:
比如很多工具明明不見得是spring 官方推出的,為什麼他們就是能跟spring 進行很好的整合呢? 比如日常使用的各種資料來源、ORM框架、紀錄檔框架、訊息佇列,他們往往能通過幾個註解輕鬆注入spring 容器中。
這是因為spring 官方不僅僅授人以魚,還授人以漁。
沒錯spring 還提供了第三方外掛接入的手段,只需要按照spring給出的規範去開發我們自己的 xml標籤、自定義註解及其配套的解析工具。
自然就能實現把自己的工具整合到spring框架上。
不過不用擔心,實際上接入spring配適的活,基本都由各個外掛官方自己幹了。 不然你以為憑什麼,你寫個 xml設定,你就敢跟人吹水:我把某某外掛整合到spring框架上了。
實際上別人已經把粘合劑生產出來了,我們只是拉了個皮條。
廢話講完,接下來就應該去看看那兩行程式碼到底幹了啥了:
XmlBeanFactory 實際上已經被廢棄了,這裡依然還要講它的目的主要是為了學習;雖然這個類被廢棄了,但是它的父類別:DefaultListableBeanFactory 至今任然是 spring 中絕對的主角之一。
這裡名為學習 XmlBeanFactory,實際上是學習它的父類別:DefaultListableBeanFactory。
都是從 xml 組態檔切入,實際上現今官方推薦使用的是:ClassPathXmlApplicationContext 而非 XmlBeanFactory。
而這裡還把 XmlBeanFactory 拿出來講,還有一個目的:
ClassPathXmlApplicationContext 足夠強大,但是它也要比 XmlBeanFactory 複雜得多;
實際上 我們對 XmlBeanFactory 的學習成果,可以作為 ClassPathXmlApplicationContext 的子集
所以 就算 XmlBeanFactory 已經廢棄了,我們還是可以繼續學習它的。
繫好安全帶,發車了。
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("bean.xml"));
這裡會有4篇部落格:
例如: beans、import、bean、alias
可以認為是我們自己對 spring 預設標籤的魔改。
還不知道需要多少篇幅介紹它
Object object = beanFactory.getBean("action");