參考:
spring 源碼分析及知識點(diǎn)總結(jié)
Spring源碼深度解析》學(xué)習(xí)筆記——Spring的整體架構(gòu)與容器的基本實(shí)現(xiàn)
Spring的整體架構(gòu):
這些模塊被總結(jié)為以下幾個部分:
- Core Container
有Core卧蜓、Beans胞此、Context和EL模塊(Expression Language)
Core和Beans模塊是框架的基礎(chǔ)部分肝劲,提供IoC(控制反轉(zhuǎn))和依賴注入特性悴了。這里的基礎(chǔ)概念是BeanFactory,它提供對Factory模式的經(jīng)典實(shí)現(xiàn)來消除對程序性單例模式的需要晶府,并真正地允許你從程序邏輯中分離出依賴關(guān)系和配置
Core模塊:Spring框架基本的核心工具類
Beans模塊:包含訪問配置文件椒袍、創(chuàng)建和管理bean以及進(jìn)行控制反轉(zhuǎn)和依賴注入操作相關(guān)的所有類
Context模塊:構(gòu)建于Core和Beans模塊基礎(chǔ)之上坛吁,提供了一種類似于JNDI注冊器的框架式的對象訪問方法摩幔。為Spring核心提供了大量擴(kuò)展
EL模塊:提供了一個強(qiáng)大的表達(dá)式語言用于在運(yùn)行時查詢和操縱對象
Data Access/Integration
JDBC彤委,數(shù)據(jù)訪問交互,對象關(guān)系映射等Web
建立Web上下文AOP
AOP模塊提供了一個標(biāo)準(zhǔn)的面向切面編程的實(shí)現(xiàn)或衡,可以定義方法攔截器和切點(diǎn)焦影,將邏輯代碼分開,降低代碼的耦合性封断,利用元數(shù)據(jù)功能斯辰,還可以將各種行為信息合并到代碼中
- Test
支持使用Junit和TestNG對Spring組件進(jìn)行測試
Spring概要
基本原理其實(shí)就是通過反射解析類及其類的各種信息,包括構(gòu)造器坡疼、方法及其參數(shù)椒涯,屬性。然后將其封裝成bean定義信息類回梧、constructor信息類废岂、method信息類、property信息類狱意,最終放在一個map里湖苞,也就是所謂的container,池等等详囤,其實(shí)就是個map财骨。
BeanFactory和BeanDefinition,一個是IOC的核心工廠接口藏姐,一個是IOC的bean定義接口隆箩,上章提到說我們無法讓BeanFactory持有一個Map<String,BeanDefinition>來完成bean工廠的功能,是因?yàn)閟pring的初始化是可以控制的羔杨,可以到用的時候才將bean實(shí)例化供開發(fā)者使用捌臊,除非我們將bean的lazy-init屬性設(shè)置為true,初始化bean工廠時采用延遲加載兜材。
寫好配置文件理澎,啟動項(xiàng)目后,框架會先按照配置文件找到對應(yīng)的包曙寡,然后解析包里面的所有類糠爬,找到所有含有@bean,@service等注解的類举庶,利用反射解析它們执隧,包括解析構(gòu)造器,方法户侥,屬性等等镀琉,然后封裝成各種信息類放到一個map里。
每當(dāng)你需要一個bean的時候添祸,框架就會從container找是不是有這個類的定義肮鏊凇?
如果找到則通過構(gòu)造器new出來(這就是控制反轉(zhuǎn)刃泌,不用你new,框架幫你new)凡壤,再在這個類找需要注入的屬性或者方法,比如標(biāo)有@autowired的屬性耙替,如果有則還是到container找對應(yīng)的解析類亚侠,new出對象,并通過之前解析出來的信息類找到setter方法俗扇,然后用該方法注入對象(這就是依賴注入)硝烂。
如果其中有一個類container里沒找到,則拋出異常铜幽,比如常見的spring無法找到該類定義滞谢,無法wire的異常串稀。
如果bean的scope是singleton,會重用狮杨。
如果scope是session母截,則該bean會放到session里面。
Spring bean作用域與生命周期
Spring通過new關(guān)鍵字將一個Bean進(jìn)行實(shí)例化橄教,Spring根據(jù)xml文件中的配置通過調(diào)用Bean中的setXXX方法填入對應(yīng)的屬性清寇、事件通知。
Spring依次檢查Bean是否實(shí)現(xiàn)了BeanNameAware护蝶、BeanFactoryAware华烟、ApplicationContextAware、BeanPostProcessor持灰、InitializingBean接口盔夜,如果有的話,依次調(diào)用這些接口使用搅方。應(yīng)用程序可以正常使用這個Bean了比吭。銷毀:如果Bean實(shí)現(xiàn)了DisposableBean接口,就調(diào)用其destroy方法姨涡。
BeanDefinition的載入和解析
對IoC容器來說衩藤,這個載入過程,相當(dāng)于把定義的BeanDefinition在IoC容器中轉(zhuǎn)化成一個Spring內(nèi)部表示的數(shù)據(jù)結(jié)構(gòu)的過程涛漂。IoC容器對Bean的管理和依賴注入功能的實(shí)現(xiàn)赏表,是通過對其持有的BeanDefinition進(jìn)行各種相關(guān)操作來完成的。這些BeanDefinition數(shù)據(jù)在IoC容器中通過一個HashMap來保持和維護(hù)匈仗。
Spring容器初始化過程
spring的IoC容器初始化包括:Bean定義資源文件的定位瓢剿、載入和注冊3個基本過程。
當(dāng) BeanDefinition 注冊完畢以后悠轩, Spring Bean 工廠就可以隨時根據(jù)需要進(jìn)行實(shí)例化了间狂。對于 XmlBeanFactory 來說,實(shí)例化默認(rèn)是延遲進(jìn)行的火架。
如何啟動spring容器
在Web項(xiàng)目中鉴象,啟動Spring容器的方式有三種,ContextLoaderListener何鸡、ContextLoadServlet纺弊、ContextLoaderPlugin。