1. 程式人生 > >《Spring原始碼深度解析》學習筆記

《Spring原始碼深度解析》學習筆記

《Spring原始碼深度解析》學習筆記——Spring的整體架構與容器的基本實現

spring框架是一個分層架構,它包含一系列的功能要素,並被分為大約20個模組,如下圖所示

這些模組被總結為以下幾個部分:

  • Core Container

    Core Container(核心容器)包含有Core、Beans、Context和Expression Language模組 
    Core和Beans模組是框架的基礎部分,提供IoC(轉控制)和依賴注入特性。這裡的基礎概念是BeanFactory,它提供對Factory模式的經典實現來消除對程式性單例模式的需要,並真正地允許你從程式邏輯中分離出依賴關係和配置

    • Core模組主要包含Spring框架基本的核心工具類
    • Beans模組是所有應用都要用到的,它包含訪問配置檔案、建立和管理bean以及進行Inversion of Control/Dependency Injection(Ioc/DI)操作相關的所有類
    • Context模組構建於Core和Beans模組基礎之上,提供了一種類似於JNDI註冊器的框架式的物件訪問方法。Context模組繼承了Beans的特性,為Spring核心提供了大量擴充套件,添加了對國際化(如資源繫結)、事件傳播、資源載入和對Context的透明建立的支援。ApplicationContext介面是Context模組的關鍵
    • Expression Language模組提供了一個強大的表示式語言用於在執行時查詢和操縱物件,該語言支援設定/獲取屬性的值,屬性的分配,方法的呼叫,訪問陣列上下文、容器和索引器、邏輯和算術運算子、命名變數以及從Spring的IoC容器中根據名稱檢索物件
  • Data Access/Integration

    • JDBC模組提供了一個JDBC抽象層,它可以消除冗長的JDBC編碼和解析資料庫廠商特有的錯誤程式碼,這個模組包含了Spring對JDBC資料訪問進行封裝的所有類
    • ORM模組為流行的物件-關係對映API,如JPA、JDO、Hibernate、iBatis等,提供了一個互動層,利用ORM封裝包,可以混合使用所有Spring提供的特性進行O/R對映,如前邊提到的簡單宣告性事務管理
  • Web

    Web上下文模組建立在應用程式上下文模組之上,為基於Web的應用程式提供了上下文,所以Spring框架支援與Jakarta Struts的整合。Web模組還簡化了處理多部分請求以及將請求引數繫結到域物件的工作。Web層包含了Web、Web-Servlet、Web-Struts和Web、Porlet模組

    • Web模組:提供了基礎的面向Web的整合特性,例如,多檔案上傳、使用Servlet listeners初始化IoC容器以及一個面向Web的應用上下文,它還包含了Spring遠端支援中Web的相關部分
    • Web-Servlet模組web.servlet.jar:該模組包含Spring的model-view-controller(MVC)實現,Spring的MVC框架使得模型範圍內的程式碼和web forms之間能夠清楚地分離開來,並與Spring框架的其他特性基礎在一起
    • Web-Struts模組:該模組提供了對Struts的支援,使得類在Spring應用中能夠與一個典型的Struts Web層整合在一起
    • Web-Porlet模組:提供了用於Portlet環境和Web-Servlet模組的MVC的實現
  • AOP

    AOP模組提供了一個符合AOP聯盟標準的面向切面程式設計的實現,它讓你可以定義例如方法攔截器和切點,從而將邏輯程式碼分開,降低它們之間的耦合性,利用source-level的元資料功能,還可以將各種行為資訊合併到你的程式碼中

    Spring AOP模組為基於Spring的應用程式中的物件提供了事務管理服務,通過使用Spring AOP,不用依賴EJB元件,就可以將宣告性事務管理整合到應用程式中

  • Test

    Test模組支援使用Junit和TestNG對Spring元件進行測試

容器的基本實現

Spring的結構組成

beans包的層級結構

beans包中的各個原始碼包的功能如下

  • src/main/java 用於展現Spring的主要邏輯
  • src/main/resources 用於存放系統的配置檔案
  • src/test/java 用於對主要邏輯進行單元測試
  • src/test/resources 用於存放測試用的配置檔案

核心類介紹

1.DefaultListableBeanFactory

XmlBeanFactory繼承自DefaultListableBeanFactory,而DefaultListableBeanFactory是整個bean載入的核心部分,是Spring註冊及載入bean的預設實現,而對於XmlBeanFactory與DefaultListableBeanFactory不同的地方其實是在XmlBeanFactory中使用了自定義的XML讀取器XmlBeanDefinitionReader,實現了個性化的BeanDefinitionReader讀取,DefaultListableBeanFactory繼承了AbstractAutowireCapableBeanFactory並實現了ConfigURableListableBeanFactory以及BeanDefinitionRegistry介面。以下是ConfigURationListableBeanFactory的層次結構圖以下相關類圖

容器載入相關類圖

類圖中各個類的作用:

  • AliasRegistry:定義對alias的簡單增刪改等操作
  • SimpleAliasRegistry:主要使用map作為alias的快取,並對介面AliasRegistry進行實現
  • SingletonBeanRegistry:定義對單例的註冊及獲取
  • BeanFactory:定義獲取bean及bean的各種屬性
  • DefaultSingletonBeanRegistry:對介面SingletonBeanRegistry各函式的實現
  • HierarchicalBeanFactory:繼承BeanFactory,也就是在BeanFactory定義的功能的基礎上增加了對parentFactory的支援
  • BeanDefinitionRegistry:定義對BeanDefinition的各種增刪改操作
  • FactoryBeanRegistrySupport:在DefaultSingletonBeanRegistry基礎上增加了對FactoryBean的特殊處理功能
  • ConfigurableBeanFactory:提供配置Factory的各種方法
  • ListableBeanFactory:根據各種條件獲取bean的配置清單
  • AbstractBeanFactory:綜合FactoryBeanRegistrySupport和ConfigurationBeanFactory的功能
  • AutowireCapableBeanFactory:提供建立bean、自動注入、初始化以及應用bean的後處理器
  • AbstractAutowireCapableBeanFactory:綜合AbstractBeanFactory並對介面AutowireCapableBeanFactory進行實現
  • ConfigurableListableBeanFactory:BeanFactory配置清單,指定忽略型別及介面等
  • DefaultListableBeanFactory:綜合上面所有功能,主要是對Bean註冊後的處理

 

2.XmlBeanDefinitionReader

XML配置檔案的讀取是Spring中重要的功能,因為Spring的大部分功能都是以配置作為切入點的,可以從XmlBeanDefinitionReader中梳理一下資原始檔讀取、解析及註冊的大致脈絡,首先看看各個類的功能

  • ResourceLoader:定義資源載入器,主要應用於根據給定的資原始檔地址返回對應的Resource
  • BeanDefinitionReader:主要定義資原始檔讀取並轉換為BeanDefinition的各個功能
  • EnvironmentCapable:定義獲取Environment方法
  • DocumentLoader:定義從資原始檔載入到轉換為Document的功能
  • AbstractBeanDefinitionReader:對EnvironmentCapable、BeanDefinitionReader類定義的功能進行實現
  • BeanDefinitionDocumentReader:定義讀取Document並註冊BeanDefinition功能
  • BeanDefinitionParserDelegate:定義解析Element的各種方法

整個XML配置檔案讀取的大致流程,在XmlBeanDefinitionReader中主要包含以下幾步處理

 

(1)通過繼承自AbstractBeanDefinitionReader中的方法,來使用ResourceLoader將資原始檔路徑轉換為對應的Resource檔案

(2)通過DocumentLoader對Resource檔案進行轉換,將Resource檔案轉換為Document檔案

(3)通過實現介面BeanDefinitionDocumentReader的DefaultBeanDefinitionDocumentReader類對Document進行解析,並使用BeanDefinitionParserDelegate對Element進行解析

 

容器的基礎XmlBeanFactory

BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));

通過XmlBeanFactory初始化時序圖看一看上面程式碼的執行邏輯

時序圖從BeanFactoryTest測試類開始,首先呼叫ClassPathResource的建構函式來構造Resource資原始檔的例項物件,這樣後續的資源處理就可以用Resource提供的各種服務來操作了

 

配置檔案封裝

Spring的配置檔案讀取是通過ClassPathResource進行封裝的,Spring對其內部使用到的資源實現了自己的抽象結構:Resource介面來封裝底層資源

public interface InputStreamSource {
    InputStream getInputStream() throws IOException;
}
public interface Resource extends InputStreamSource {
    boolean exists();

    boolean isReadable();

    boolean isOpen();

    URL getURL() throws IOException;

    URI getURI() throws IOException;

    File getFile() throws IOException;

    long lastModified() throws IOException;

    Resource createRelative(String var1) throws IOException;

    String getFilename();

    String getDescription();
}

InputStreamSource封裝任何能返回InputStream的類,比如File、Classpath下的資源和Byte Array等, 它只有一個方法定義:getInputStream(),該方法返回一個新的InputStream物件

Resource介面抽象了所有Spring內部使用到的底層資源:File、URL、Classpath等。首先,它定義了3個判斷當前資源狀態的方法:存在性(exists)、可讀性(isReadable)、是否處於開啟狀態(isOpen)。另外,Resource介面還提供了不同資源到URL、URI、File型別的轉換,以及獲取lastModified屬性、檔名(不帶路徑資訊的檔名,getFilename())的方法,為了便於操作,Resource還提供了基於當前資源建立一個相對資源的方法:createRelative(),還提供了getDescription()方法用於在錯誤處理中的列印資訊

對不同來源的資原始檔都有相應的Resource實現:檔案(FileSystemResource)、Classpath資源(ClassPathResource)、URL資源(UrlResource)、InputStream資源(InputStreamResource)、Byte陣列(ByteArrayResource)等,相關類圖如下所示

 

 

 

 

 

分類: Spring學習(使用及原始碼學習)

標籤: spring原始碼 spring