《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