spring原始碼個人總結(待完成)
一、模組劃分
-
Core Container
-
Core 核心工具類
-
Beans 包含配置檔案、建立和管理bean和IOC用到的類
-
Context 構建在Core和Beans模組基礎上,新增國際化,事件傳播,資源載入等,ApplicationContext介面是關鍵
-
Expression Language模組是表示式語言EL的包
-
-
Data Access/Integration
-
JDBC 提供JDBC的抽象層
-
ORM 提供流行ORM框架的互動封裝
-
OXM Object/xml對映的抽象
-
JMS 製造和消費訊息特性
-
Transaction 支援程式設計和宣告性事務管理
-
-
Web
-
Web 基礎的面向Web,比如多檔案上傳,servlet listeners初始化IOC容器,面向web的應用上下文
-
Web-Servlet 包含SpringMVC的實現
-
Web-Struts 對Struts的支援
-
Web-porlet 對Portlet的支援
-
-
AOP
-
Aspects 對AspectJ的支援
-
Instrumentation 對class instrumentation和classloader實現
-
-
Test
二、容器的類關係
重要的幾個
-
DefaultListableBeanFactory :spring載入bean的預設實現
-
XmlBeanDefinitionReader:用來讀xml檔案的
-
XmlBeanFactory: 常用這個讀xml來建容器
三、ApplicationContext初始化流程
-
ClassPathXmlApplicationContext為入口構造方法中有個refresh()方法用來初始化Spring
-
refresh執行的大致流程:
-
prepareRefresh()——————————初始化準備和驗證系統屬性環境變數啥的
-
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); ——————————初始化BeanFactory
-
prepareBeanFactorybeanFactory()——————————填充BeanFactory
-
postProcessBeanFactory(beanFactory)——————————額外處理子類覆蓋方法
-
invokeBeanFactoryPostProcessors(beanFactory);——————————啟用各Factory處理器
-
registerBeanPostProcessors(beanFactory);———————————–註冊bean處理器
-
initMessageSource();——————————————————-初始化Message,國際化
-
initApplicationEventMulticaster();—————————————–初始化應用訊息廣播
-
onRefresh();—————————————————————留給子類初始化其它Bean
-
registerListeners();——————————————————bean中查詢Listener,註冊到廣播器
-
beanFactory.preInstantiateSingletons();————————————
-
publishEvent(new ContextRefreshedEvent(this));—————————–
-
-
初始化準備和驗證系統屬性環境變數
-
解析XML並且初始化工廠類,BeanFactory工廠提供了獲得bean例項的能力,通過AbstractApplicationContext類中的obtainFreshBeanFactory方法呼叫refreshBeanFactory例項化一個預設的BeanFactory工廠DefaultListableBeanFactory,然後呼叫loadBeanDefinitions裝載配置檔案,解析配置檔案(XmlBeanDefinitionReader)時會建立BeanDefinition並且放到容器DefaultListableBeanFactory中去。
-
判斷hasBeanFactory則解除安裝Bean並closeBeanFactory
-
建立DefaultListableBeanFactory
-
為它指定序列化id
-
customizeBeanFactory,定製BeanFactory
-
在這裡設定@Qualifier和@Autowired的解析器,beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver())
-
byType注入時,解析autowire會呼叫getAutowireCandidateResolver().getSuggestedValue(descriptor),上面的解析器就實現了getSuggestedValue
-
-
-
載入BeanDefinition
-
全域性變數jiluBeanFactory例項
-
-
填充BeanFactory,比如@Qualifer和@Autowired在這裡增加的支援
-
設定beanFactory的classLoader為當前Context的classLoader
-
SPEL支援
-
屬性編輯器支援
-
比如注入的時候Date無法被識別
-
-
新增BeanPostProcessor
-
新增ApplicationContextAwareProcessor處理器,beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
-
-
增加一些內建類資訊注入,設定依賴功能可忽略的介面,註冊一些固定依賴
-
增加AspectJ支援
-
-
子類用的
-
執行工廠後置處理器,這時會查詢所有BeanFactory(DefaultListableBeanFactory)工廠中的bean找出所有BeanFactoryPostProcessor實現類bean,並且呼叫方法postProcessBeanDefinitionRegistry,這個方法可以在bean例項化之前修改配置資訊(比如變數值)
-
典型的BeanFactoryPostProcessor就是PropertyPlaceHolderConfigurer,bean描述檔案中${}這昂的變數引用,就靠它
-
-
註冊後置處理器,這時會查詢所有BeanFactory(DefaultListableBeanFactory)工廠中的bean找出所有BeanPostProcessor實現類bean,並且把他們註冊到BeanFactory容器中去,和第3種工廠後置處理器的區別是BeanFactoryPostProcessor會立即呼叫,而BeanPostProcessor註冊到BeanFactory中
-
PS:使用者自定義BeanPostProcessor
-
-
預設註冊一個bean名稱為messageSource的bean用於國際化處理,這裡Spring自帶很多種實現,這個方法會先查詢BeanFactory中的bean是否有messageSource名稱的bean如果沒有給一個預設的實現DelegatingMessageSource PS:使用者可以自定義名稱為messageSource的bean,只需要實現MessageSource即可
-
Spring事件體系包括三個元件:事件,事件監聽器,事件廣播器。這裡是初始化事件廣播器,如果使用者有自定義applicationEventMulticaster名稱的bean並且實現ApplicationEventMulticaster則不需要處理,如果沒有就給一個預設的實現SimpleApplicationEventMulticaster
-
使用者可以自定義名稱applicationEventMulticaster並且實現ApplicationEventMulticaster介面的bean
-
沒有自定義就用預設的,initApplicationEventMulticaster方法初始化
-
實際接收事件被呼叫的方法是multicastEvent(ApplicationEvent event)
-
-
子類用的
-
Spring事件體系包括三個元件:事件,事件監聽器,事件廣播器。這裡是事件監聽器,上下文會在BeanFactory找到所有實現ApplicationListener的bean然後新增到事件廣播器ApplicationEventMulticaster中去
-
硬編碼註冊或者配置檔案註冊,都是getApplicationEventMulticaster.addApplicationListener(listener)
-
-
初始化單例的bean,例項化BeanFactory中所有的bean,(Spring配置的是單例設定scope=”prototype”可以配置多例模式)
-
釋出上下文重新整理事件,事件廣播器負責將些事件廣播到每個註冊的事件監聽器中,容器啟動完成
四、bean載入流程
-
轉換對應beanName,transformedBeanName
-
可能是別名alias,也可能是FactoryBean帶&的bean,去掉&
-
-
嘗試從快取中載入單例, getSingleton
-
見五
-
-
例項化,getObjectForBeanInstance
-
如果快取中得到bean的原始狀態則需要例項化,因為快取中可能是最原始的bean狀態,比如工廠bean,需要的是factory-method中的bean
-
-
原型模式迴圈依賴檢查,isPrototypeCurrentlyInCreation
-
原型模式有迴圈依賴直接拋異常
-
-
檢查parentBeanFactory
-
如果父工廠不為null,且當前的beanName不在XML配置檔案中,就只能呼叫父工廠的getBean找
-
為啥要用工廠
-
-
儲存xml的GernericBeanDefinition轉為RootBeanDefinition, getMergedLocalBeanDefinition和checkMergedBeanDefinition
-
如果BeanName是子Bean會合並父類相關屬性
-
-
尋找依賴,getDependsON
-
先初始化依賴,getBean然後registerDependentBean
-
-
根據scope建立bean
-
無論單例、原型還是request都要調createBean和getObjectForBeanInstance
-
getSingleton(beanName,new ObjectFactory)
-
為啥要Factory呢
-
-
beforePrototypeCreation,然後create,然後afterPrototypeCreation
-
其它的根據scope物件整
-
-
型別轉換,根據requiredType轉換
五、快取中獲取單例bean,getSingleton方法
-
引數為beanName和是否允許早期依賴的標記
-
檢查快取this.singletonObjects中是否有
-
為空,鎖定this.singletonObjects
-
檢查this.earlySingletonObjects中是否有
-
為空,且標識為true,從this.singletionFactories中獲取singletionFactory
-
為啥需要factory。。。。。
-
-
如果不為null,呼叫singletionFactory.getObject(),記錄在earlySingletonObjects中,從singletionFactories中刪除
六、直接獲取單例,也是getSingleton方法
-
引數是beanName和singletonFactory
-
加鎖this.singletonObjects
-
快取中檢查是否有bean
-
為空,beforeSingletonCreation記錄beanName正在載入的狀態,記載this.singletonsCurrentlyInCreation中,用於檢查迴圈依賴
-
singletonFactory.getObject()初始化bean
-
呼叫載入單例後的處理方法
-
afterSingletonCreation從載入狀態中移除bean
-
addSingleton,加鎖this.singletonObjects,寫入singletonObjects,從early和工廠快取中刪除
-
為啥又加鎖一次this.singletonObjects
-
-
返回處理結果
七、singletonFactory中的getObject與createBean
-
上面也看到了傳給getSingleton的是一個匿名singletonFactory,實現了個getObject,中間有createBean方法
-
根據class屬性或者className解析Class
-
標記驗證override
-
這塊再看看,啥堆methodOverrides動態生成代理了就
-
-
應用初始化前的後處理器,解析bean是否存在短路操作
-
短路?
-
-
建立bean,doCreateBean
-
如果是單例先清除快取
-
例項化bean,beanDefinition轉換為BeanWrapper, createBeansInstance
-
如果存在工廠方法(RootBeanDefinition存在factoryMethodName屬性或者說配置檔案中有factory-method)則使用工廠方法初始化
-
根據引數鎖定建構函式
-
根據指定的引數獲取
-
不行從快取中獲取
-
不行從配置檔案中獲取
-
-
都不存在則預設初始化
-
例項化策略非簡單的反射,判斷如果beanDefinition.getMethodOverrides為空就反射,沒有就通過動態代理增強
-
-
枷鎖例項的postProcessingLock,應用MergedBeanDefinitionPostPrecessor
-
bean合併後的處理,Autowired主節通過此方法實現型別的預解析
-
-
處理依賴
-
當單例且允許迴圈依賴且當前bean在建立中時,earlySingletonExposure為true
-
addSingletonFactory,引數beanName和新 ObjectFactory工廠
-
工廠中getObject只有return getEarlyBeanReference,AOP就是在這裡將advice動態織入bean中
-
-
-
屬性注入bean
-
InstantiationAwareBeanPostProcessor處理器的postProcessAfterInstantiation方法應用
-
控制是否繼續屬性填充
-
-
根據byName/byType,提取依賴的bean
-
autowireByName,遞迴getBean,註冊依賴
-
autowireByType,哇這個超複雜。。。引申一個註解Autowired到List上會怎樣的問題
-
-
InstantiationAwareBeanPostProcessor處理器的postProcessPropertyValues方法應
-
將屬性填充到BeanWarapper
-
-
呼叫initializeBean方法,比如init-method
-
迴圈依賴檢查
-
如果配置了destory-method,註冊DisposableBean
-
八、設計模式
a. 簡單工廠:並不屬於23種設計模式,BeanFactory就是傳入一個標識來獲取bean物件
-
即靜態方法模式,一個工廠一個產品介面多產品,工廠根據傳入的name輸出對應product
-
例項的建立與使用分開,解耦client與具體產品(client依賴工廠和product介面);例項化的工作統一在工廠中,便於全域性唯一
-
違反開閉,加產品得改程式碼;工廠類出問題整體都受影響;靜態方法不被重寫工廠們無法有繼承關係
b. 工廠方法:FacotyBean就是工廠方法模式
-
一個工廠介面多工廠一個產品介面多產品,一一對應
-
符合開閉,加產品直接加工廠和產品,不修改工廠程式碼;符合單一職責;可形成繼承
-
工廠和產品成對增加了複雜度和開銷;一個工廠一個產品;系統抽象性增加
c. 單例模式:單例Bean,不過這僅僅是提供了全域性訪問的BeanFactory,並沒有從構造器級別去保證只有一個單例
d. 介面卡模式:AOP中使用Advice(通知)來增強被代理類的功能,BeforeAdvice、AfterReturningAdvice、ThreowSadvice每個Advice有對應的攔截器MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor,Spring通過適配者講Advice封裝成Interceptor
e. 裝飾器模式:動態的給物件新增額外的職責
-
spring中名字帶Wrapper和Decorator的類,比如BeanDefinition變BeanWarrper(我猜的)
-
代理偏重自己不知道的流程,裝飾器偏重物件
-
開閉原則的體現,耦合低,擴充套件靈活,防止繼承爆炸
-
缺點:過多裝飾一個類,增加複雜度
f. 代理模式:AOP
g. 觀察者模式:ApplicationListener,如果容器中有一個ApplicationListener Bean,每當ApplicationContext釋出ApplicationEvent時,ApplicationListener Bean將自動被觸發
h. 策略模式:例項化物件時用到,根據建立物件的三個分支( 工廠方法、有參構造方法、無參構造方法 )
-
createBeanInstance的時候
i. 模板方法模式:JdbcTemplate,事務Template
九、bean生命週期
十、