想來從開始接觸和使用Spring已四年有餘,雖然說使用不成問題,但對其內部具體實現實現原理卻只知一二,因而乎痛下決心要好好擼一遍Spring,以便更好地使用Spring的高級功能並且還能知其然知其因此然,吸取它的好思想、設計模式等等,從如今開始每次把get到的相關內容跟各位客官分享,願一塊兒進步,一塊兒走的更遠!除了Spring,後續咱們也嘗試着擼Mybatis等框架,以求功力大增。設計模式
BeanFactory,毫無疑問,就是生產Bean的工廠。咱們都知道Spring框架提倡咱們使用POJO,若是咱們把每一個業務對象都當作是一個JavaBean的話,咱們就能很好的理解這個名字的由來了。Spring中生產Bean的過程並無想象中的簡單,這個工廠至少還應該具備業務對象的註冊以及對象間依賴關係綁定等功能,這樣看起來纔是一個完整的工廠。框架
咱們都知道蘋果公司將本身生產的或者從別的供應商那裏採購的手機零件輸送到富士康工廠,那就能夠在富士康生產線的最後一個節點獲取成品的蘋果手機。若是咱們能夠把BeanFactory看做是富士康廠,那手機配件就是各個業務對象。也就是說咱們能夠直接從BeanFactory中獲取已經組裝好的所需對象,而不須要關心該對象究竟是如何被組裝出來的。ide
對於咱們這些使用框架的來講,使用BeanFactory其實很簡單,由於它已經提供了取得組裝完成的對象的方法,源碼以下:學習
public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; boolean containsBean(String name); boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException; Class<?> getType(String name) throws NoSuchBeanDefinitionException; String[] getAliases(String name); }
這些方法大多都是查詢業務對象的,如查找某個對象是否存在的方法(containsBean),獲取某個對象的方法(getBean),固然因爲須要存在諸多的重載方法。ui
在BeanFactory沒有出現以前,咱們若是須要某個類的對象毫無疑問是直接new一個,出來,那如今只須要將這些工做讓BeanFactory來幹就行了,具體實例以下:設計
AClass a = new AClass(); BClass b = new BClass(); CClass c = new CClass(); a.setB(b); a.setC(c); a.doSomeThing();
有了BeanFactory以後,咱們須要畫出一個生產圖紙並告訴它就能夠了,以下:代理
<beans> <bean id="a" class="AClass"> <property name="b" ref="b"/> <property name="c" ref="c"/> </bean> <bean id="b" class="BClass"></bean> <bean id="c" class="CClass"></bean> </beans>
而後咱們能夠以下調用:code
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("上面配置文件位置")); AClass a = (AClass)factory.getBean("a"); a.doSomeThing();
乍看起來好像改變並非很大對不對?不要緊看官別急,隨着學習的深刻咱們會慢慢的能體會到其中的奧祕。對象
實際上,BeanFactory並不負責直接維護Bean關係,而是將Bean之間的關係委託給BeanDefinitionRegistry來進行管理。在Spring中,每個Bean的原信息都會被看作是一個BeanDefinition,也就是Bean定義。那BeanDefinitionRegistry經過管理這些BeanDefinition從而實現對Bean的關係。咱們能夠把BeanDefinition看作是圖書館裏的一本書,而BeanDefinitionRegistry就是圖書館的書架。從上文源碼中咱們得知BeanFactory實際上是個接口,那它的功能終究是會由它的實現類來完成,DefaultListableBeanFactory就是這個一個實現類。這幾個概念之間的UML類圖以下:blog
在BeanFactory中,每個交給它管理的對象,在BeanDefinitionRegistry中都會有一個BeanDefinition實例跟關聯對象綁定,BeanDefinition實例負責保存該Bean的原信息,如class類型、構造方法參數等。當咱們向BeanFactory索要bean時,它就根據這些原信息生成一個可用的對象給到咱們。
經過上面的內容,咱們不難發現,對於Spring來講,在初始化階段要首先完成三件事:收集Bean原信息、註冊Bean原信息、根據原信息生成Bean代理對象,只有這樣才能很好爲咱們服務。收集時能夠經過XML文件收集、能夠經過TXT文件收集、能夠經過代碼(包括經過註解和手動調用收集方法)收集。註冊就是將收集到Bean原信息保存到BeanDefinitionRegistry中以便後續使用。
阿豪說學到了?請我喝杯咖啡吧~