1. 程式人生 > >spring原始碼個人總結(待完成)

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初始化流程

  1. ClassPathXmlApplicationContext為入口構造方法中有個refresh()方法用來初始化Spring 

    1. refresh執行的大致流程: 

    2. prepareRefresh()——————————初始化準備和驗證系統屬性環境變數啥的

    3. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  ——————————初始化BeanFactory

    4. prepareBeanFactorybeanFactory()——————————填充BeanFactory

    5. postProcessBeanFactory(beanFactory)​——————————額外處理子類覆蓋方法

    6. invokeBeanFactoryPostProcessors(beanFactory);——————————啟用各Factory處理器

    7. registerBeanPostProcessors(beanFactory);———————————–註冊bean處理器

    8. initMessageSource();——————————————————-初始化Message,國際化

    9. initApplicationEventMulticaster();—————————————–初始化應用訊息廣播

    10. onRefresh();—————————————————————留給子類初始化其它Bean

    11. registerListeners();——————————————————bean中查詢Listener,註冊到廣播器

    12. beanFactory.preInstantiateSingletons();————————————

    13. publishEvent(new ContextRefreshedEvent(this));—————————–

  2. 初始化準備和驗證系統屬性環境變數

  3. 解析XML並且初始化工廠類,BeanFactory工廠提供了獲得bean例項的能力,通過AbstractApplicationContext類中的obtainFreshBeanFactory方法呼叫refreshBeanFactory例項化一個預設的BeanFactory工廠DefaultListableBeanFactory,然後呼叫loadBeanDefinitions裝載配置檔案,解析配置檔案(XmlBeanDefinitionReader)時會建立BeanDefinition並且放到容器DefaultListableBeanFactory中去。

    1. 判斷hasBeanFactory則解除安裝Bean並closeBeanFactory

    2. 建立DefaultListableBeanFactory​

    3. 為它指定序列化id

    4. customizeBeanFactory,定製BeanFactory

      1. 在這裡設定@Qualifier和@Autowired的解析器,beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver())

        1. byType注入時,解析autowire會呼叫getAutowireCandidateResolver().getSuggestedValue(descriptor),上面的解析器就實現了getSuggestedValue

    5. 載入BeanDefinition

    6. 全域性變數jiluBeanFactory例項​

  4. 填充BeanFactory,比如@Qualifer和@Autowired在這裡增加的支援

    1. 設定beanFactory的classLoader為當前Context的classLoader

    2. SPEL支援​

    3. 屬性編輯器支援

      1. 比如注入的時候Date無法被識別

    4. 新增BeanPostProcessor

      1. 新增ApplicationContextAwareProcessor處理器,beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

    5. 增加一些內建類資訊注入,設定依賴功能可忽略的介面,註冊一些固定依賴

    6. 增加AspectJ支援​

  5. 子類用的​

  6. 執行工廠後置處理器,這時會查詢所有BeanFactory(DefaultListableBeanFactory)工廠中的bean找出所有BeanFactoryPostProcessor實現類bean,並且呼叫方法postProcessBeanDefinitionRegistry,這個方法可以在bean例項化之前修改配置資訊(比如變數值) 

    1. 典型的BeanFactoryPostProcessor就是PropertyPlaceHolderConfigurer,bean描述檔案中${}這昂的變數引用,就靠它

  7. 註冊後置處理器,這時會查詢所有BeanFactory(DefaultListableBeanFactory)工廠中的bean找出所有BeanPostProcessor實現類bean,並且把他們註冊到BeanFactory容器中去,和第3種工廠後置處理器的區別是BeanFactoryPostProcessor會立即呼叫,而BeanPostProcessor註冊到BeanFactory中 

    1. PS:使用者自定義BeanPostProcessor

  8. 預設註冊一個bean名稱為messageSource的bean用於國際化處理,這裡Spring自帶很多種實現,這個方法會先查詢BeanFactory中的bean是否有messageSource名稱的bean如果沒有給一個預設的實現DelegatingMessageSource  PS:使用者可以自定義名稱為messageSource的bean,只需要實現MessageSource即可

  9. Spring事件體系包括三個元件:事件,事件監聽器,事件廣播器。這裡是初始化事件廣播器,如果使用者有自定義applicationEventMulticaster名稱的bean並且實現ApplicationEventMulticaster則不需要處理,如果沒有就給一個預設的實現SimpleApplicationEventMulticaster 

    1. 使用者可以自定義名稱applicationEventMulticaster並且實現ApplicationEventMulticaster介面的bean

    2. 沒有自定義就用預設的,initApplicationEventMulticaster​方法初始化

    3. 實際接收事件被呼叫的方法​是multicastEvent(ApplicationEvent event)

  10. 子類用的

  11. Spring事件體系包括三個元件:事件,事件監聽器,事件廣播器。這裡是事件監聽器,上下文會在BeanFactory找到所有實現ApplicationListener的bean然後新增到事件廣播器ApplicationEventMulticaster中去

    1. 硬編碼註冊或者配置檔案註冊,都是getApplicationEventMulticaster.addApplicationListener(listener)

  12. 初始化單例的bean,例項化BeanFactory中所有的bean,(Spring配置的是單例設定scope=”prototype”可以配置多例模式)

  13. 釋出上下文重新整理事件,事件廣播器負責將些事件廣播到每個註冊的事件監聽器中,容器啟動完成

 

四、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生命週期

 

十、