Spring5IOC容器解析——Bean與BeanDefinition

概述

Spring是一個開放源代碼的設(shè)計層面框架,他解決的是業(yè)務(wù)邏輯層和其他各層的松耦合問題,因此它將面向接口的編程思想貫穿整個系統(tǒng)應(yīng)用。Spring是于2003 年興起的一個輕量級的Java 開發(fā)框架,由Rod Johnson創(chuàng)建。簡單來說,Spring是一個分層的JavaSE/EE full-stack(一站式) 輕量級開源框架。

spring的整體架構(gòu)

Spring框架是一個分層架構(gòu),它包含一系列的功能要素,并被分為大約20個模塊,如下圖所示:


圖片來自https://docs.spring.io/spring/docs/4.3.21.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#overview-modules

從上圖spring framework整體架構(gòu)圖可以看到,這些模塊被總結(jié)為以下幾個部分:

1、Core Container

Core Container(核心容器)包含有Core、Beans、Contexts 和 Expression Language模塊。
Core 和 Beans模塊是框架的基礎(chǔ)部分,提供 IoC(Inversion of Control,控制反轉(zhuǎn)) 和依賴注入特性。

  • Core模塊:主要包含Spring 框架基本的核心工具類,Spring的其他組件都要使用到這個包里的類,Core 模塊是其他組件的基本核心,當(dāng)然也可以在自己的應(yīng)用系統(tǒng)中使用這些工具類
  • Beans模塊:是框架是所有應(yīng)用都要用到的,它包含訪問配置文件、創(chuàng)建和管理bean以及進(jìn)行 Inversion of Control / Dependency Injection(IoC/DI)操作相關(guān)的所有類
  • Context模塊:構(gòu)建于 Core 和 Beans 模塊的基礎(chǔ)之上,提供了一種類似于 JNDI 注冊器的框架式的對象訪問方法。Context 模塊繼承了 Beans 的特性,為 Spring 核心提供了大量擴(kuò)展,提供了對國際化(如資源綁定)、事件傳播、資源加載和對 Context 的透明創(chuàng)建的支持。 Context 模塊同時也支持 J2EE的一些特性,例如 EJB、JMX和基礎(chǔ)的遠(yuǎn)程處理。ApplicationContext 接口是 Context 模塊的關(guān)鍵。
  • Expression Language模塊:提供了一個強(qiáng)大的表達(dá)式語言用于在運行時查詢和操縱對象。它是 JSP 2.1 規(guī)范中定義的 unifed express language 的一個擴(kuò)展。該語言支持設(shè)置/獲取屬性的值,屬性的分配,方法的調(diào)用,訪問數(shù)組上下文、容器和索引器、邏輯和算數(shù)運算符、命名變量以及從 Spring 的 IoC 容器中根據(jù)名稱檢索對象。

2、Data Access/Integration

Data Access/Interation 層包含有 JDBC、ORM、OXM、JMS 和 Transaction 模塊

  • JDBC模塊:提供了一個 JDBC 抽象層,它可以消除冗長的 JDBC 編碼和解析數(shù)據(jù)庫廠商特有的錯誤代碼。此模塊包含了 Spring 對 JDBC 數(shù)據(jù)訪問進(jìn)行封裝的所有類。
  • ORM模塊:為流行的對象-關(guān)系映射 API ,例如 JPA、JDO、 Hibernate、 iBatis等,提供了一個交互層。利用 ORM 封裝包,可以混合使用 Spring 提供的特性進(jìn)行 O/R映射(Object/Relation)。
  • OXM模塊:提供了一個對 Object/XML映射實現(xiàn)的抽象層,Object/XML 映射實現(xiàn)包括 JAXB、Castor 、XMLBeans 、JiBX 和 XStream。
  • JMS (Java Messaging Service) 模塊:主要包含了一些制造和消費消息的特性。
  • Transaction模塊:支持編程和生命性的事務(wù)管理,這些事物必須實現(xiàn)特定的接口,并且對所有的 POJO 都適用。

3、Web

Web 上下文模塊建立在應(yīng)用程序上下文模塊之上,為基于 Web 的應(yīng)用程序提供了上下文。所以 Spring 框架支持 Jakarta Struts 的集成。Web 模塊還簡化了處理多部分請求以及將請求參數(shù)綁定到域?qū)ο蟮墓ぷ?。Web 層包含了 Web、Web-Servlet、Web-Struts 和 Web-Porlet模塊。

  • Web模塊:提供了基礎(chǔ)的面向 Web 的集成特性。例如,多文件上傳、使用 servlet listeners 初始化 IoC 容器以及一個面向 Web 的應(yīng)用上下文。它還包含 Spring 遠(yuǎn)程支持中 Web 的相關(guān)部分
  • Web-Servlet模塊:web.servlet.jar: 該模塊包含 Spring 的 model-view-controller (MVC) 實現(xiàn)。 Spring 的 MVC框架使得模型范圍內(nèi)的代碼和 web forms之間能夠清楚的分離開來,并與 Spring 框架的其他特性集成在一起。
  • Web-Struts模塊:該模塊提供了對 Struts 的支持,使得類在 Spring 應(yīng)用中能夠與一個典型的 Struts Web 層集成在一起。該支持在 Spring 3.0 中是 deprecated 的。
  • Web-Porlet模塊:提供了用于 Porlet 環(huán)境和 Web-Servlet 模塊的 MVC 的實現(xiàn)。

4、AOP

AOP 模塊提供了一個符合 AOP 聯(lián)盟標(biāo)準(zhǔn)的面向切面編程的實現(xiàn),它讓你可以定義例如方法攔截器和切點,從而將邏輯代碼分開,降低它們之間的耦合性。利用 source-level 的元數(shù)據(jù)功能,還可以將各種行為信息合并到你的代碼中。

通過配置管理特性,Spring AOP 模塊直接將面向切面的編程功能集成到了 Spring 框架中,所以可以很容易的使 Spring 框架管理的任何對象支持 AOP,不用依賴 EJB 組件,就可以將聲明性食物管理集成到應(yīng)用程序中。

  • Aspects模塊:提供了對 AspectJ 的集成支持。
  • Instrumentation模塊:提供了 class instrumentation 支持和 classloader 實現(xiàn),使得可以在特定應(yīng)用服務(wù)器上使用。

5、Test

Test模塊支持使用Junit和TestNG對Spring組件進(jìn)行測試

Bean與BeanDefinition

BeanDefinition與Bean的關(guān)系, 就好比類與對象的關(guān)系,類在spring的數(shù)據(jù)結(jié)構(gòu)就是BeanDefinition。根據(jù)BeanDefinition得到的對象就是我們需要的Bean。

我認(rèn)為理解Bean與BeanDefinition是理解spring的整個架構(gòu)的基礎(chǔ)與關(guān)鍵。我將從Bean與BeanDefinition開始慢慢撥開spring的內(nèi)幕。

研究bean與BeanDefinition,我認(rèn)為可以分為兩部分來循序漸進(jìn)的解析。

  • 一方面從定義入手:研究Bean/BeanDefinition在spring中的定義.
  • 另一方面從動作(操作)入手:研究Bean/BeanDefinition的相關(guān)操作。

BeanDefinition

BeanDefinition是bean在spring中的描述,有了BeanDefinition我們就可以創(chuàng)建Bean,BeanDefinition是Bean在spring中的定義形態(tài)

接下來我們看看BeanDefinition的相關(guān)接口與類。

定義

BeanDefinition接口頂級基礎(chǔ)接口,用來描述Bean,里面存放Bean元數(shù)據(jù),比如Bean類名、scope、屬性、構(gòu)造函數(shù)參數(shù)列表、依賴的bean、是否是單例類、是否是懶加載等一些列信息。

  • BeanMetadataElement接口:BeanDefinition元數(shù)據(jù),返回該Bean的來源
  • AttributeAccessor接口:提供對BeanDefinition屬性操作能力,
  • AbstractBeanDefinition類:抽象類統(tǒng)一實現(xiàn)了BeanDefinition定義的一部分操作,可以說是定義了BeanDefinition很多默認(rèn)的屬性。 正是在AbstractBeanDefinition基礎(chǔ)上, Spring衍生出了一些列BeaDefinition。

這里我們可以關(guān)注下重寫的equals(),hashcode(), toString()方法

此外initMethodName屬性,destroyMethodName 屬性, 這兩個屬性bean的生命周期有關(guān),此處只提一句,后續(xù)講解。

接下來。我們看看從AbstractBeanDefinition上衍生出來的幾個類

  • RootBeanDefinition:代表一個xml,java Config來的BeanDefinition

  • ChildBeanDefinition:可以讓子BeanDefinition定義擁有從父母哪里繼承配置的能力

  • GenericBeanDefinition:spring2.5后注冊bean首選的是GenericBeanDefinition。GenericBeanDefinition允許動態(tài)的設(shè)置父bean.GenericBeanDefinition可以作為RootBeanDefinition與ChildBeanDefinition的替代品。

  • AnnotatedBeanDefinition接口:表示注解類型BeanDefinition。有兩個重要的屬性,AnnotationMetadata,MethodMetadata分別表示BeanDefinition的注解元信息和方法元信息
    實現(xiàn)了此接口的BeanDefinition可以獲取到注解元數(shù)據(jù)和方法元數(shù)據(jù)。

  • AnnotatedGenericBeanDefinition類:表示@Configuration注解注釋的BeanDefinition類

  • ScannedGenericBeanDefinition類:表示@Component、@Service、@Controller等注解注釋的Bean類

操作

動作也可分為兩種:

  • 一種是針對自身的操作: 自提提供給外部的可以操作其本身的動作
  • 另一種是外部對BeanDefinition的操作

BeanDefinitionRegistry接口:具有增,查,刪BeanDefinition的能力。一次只能注冊一個BeanDefinition。

實現(xiàn)類SimpleBeanDefinitionRegistry,DefaultListableBeanFactory,GenericApplicationContext等
一般實現(xiàn)類里都都有一個private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap()來存儲BeanDefinition。


  • BeanDefinitionReader接口: 既可以使用BeanDefinitionRegistry構(gòu)造。也可以通過loadBeanDefinitions把配置加載為多個BeanDefinition并注冊到BeanDefinitionRegistry中。
    可以說是高效版本的BeanDefinitionRegistry.
    實現(xiàn)類有
    XmlBeanDefinitionReader從xml中讀取BeanDefinition;
    PropertiesBeanDefinitionReader從Properties文件讀取BeanDefinition

  • AnnotatedBeanDefinitionReader類:對帶有注解的BeanDefinition進(jìn)行注冊

  • ClassPathBeanDefinitionScanner類:可以掃描到@Component @Repository @Service @Controller 的BeanDefinition注冊到容器中。

其他形態(tài)

BeanDefinitionHolder: BeanDefinition包裝類。

Bean

Bean是我們需要的對象,是我們從spring內(nèi)得到的結(jié)果,也就是對象實例

定義

從定義層面看Bean其實就是我們需要的對象.

操作

我們來看看Bean在spring有哪些操作相關(guān)的接口或類。

  • SingletonBeanRegistry接口:與BeanDefinition的注冊相應(yīng)的。Bean的操作也有一個類似的接口來操作Bean.SingletonBeanRegistry接口提供了對Bean的注冊,獲取,存在性判斷等功能。
  • InitializingBean:對于實現(xiàn) InitializingBean的Bean,它將執(zhí)行 afterPropertiesSet(); 在所有的 bean 屬性被設(shè)置之后。
  • InstantiationStrategy:提供 Bean實例化的策略接口。
  • DisposableBean:對于 實現(xiàn)了DisposableBean的Bean ,它將運行 destroy()在 Spring 容器釋放該 bean 之后。
  • FactoryBean:生產(chǎn)Bean的Bean。
其他形態(tài)
  • BeanWrapper:對Bean的包裝.BeanWrapper可以看作是一個從 BeanDefinition 到 Bean 過程中間的產(chǎn)物,可以稱為”低級 bean“,在一般情況下,我們不會在實際項目中用到它。BeanWrapper 是 Spring 框架中重要的組件類,它就相當(dāng)于一個代理類,Spring 委托 BeanWrapper 完成 Bean 屬性的填充工作。在 bean 實例被 InstantiatioonStrategy 創(chuàng)建出來后,Spring 容器會將 Bean 實例通過 BeanWrapper 包裹起來,是通過 BeanWrapper.setWrappedInstance() 完成的
總結(jié):

BeanDefinition是物料,Bean是成品,理解BeanDefinition與Bean的關(guān)系是理解spring的基礎(chǔ)。

參考:
https://www.cnblogs.com/EnzoDin/p/6556825.html

https://www.cnblogs.com/java-chen-hao/p/11046190.html

https://www.cnblogs.com/smallstudent/p/11638112.html

https://www.cnblogs.com/ITtangtang/p/3978349.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容