spring技术内幕——深入解析spring架构与设计原理
林納斯·托瓦茲(Linus Torvalds)說:“我從心底認為,優秀的程序員與平庸的程序員之間的區別,是在于認為自己的代碼重要還是數據結構更加重要。平庸的程序員眼里只有代碼,優秀的程序員則關注數據結構及之前的關系?!?
1、spring的設計理念
- spring提供了一個輕量級的開發框架,抽象了實際開發中的很多共性問題;在javaee的開發中,支持pojo和使用javabean的開發方式,使應用面向接口開發、充分支持OO;
- 通過spring的ioc容器,將復雜的對象耦合關系變成了一個文本化、外部化的工作,通過一個或幾個xml文件來方便的對應用對象的耦合關系進行維護、修改和瀏覽,極大地簡化了應用開發;
- 通過ioc容器的依賴反轉,將依賴關系從java對象中解放出來,交給了ioc容器完成,對象之間的關系進行了解耦,對象——對象之間的關系轉化成了對象——IOC容器——對象的關系;
- IOC容器和AOP模塊是spring最為基礎的底層抽象,IOC來管理bean對象,aop以動態和非侵入的方式增強服務功能。
2、spring的整體架構
springioc、spring aop、springmvc、springjdbc/orm、spring事務處理、spring的遠端調用、spring應用;其中aop以縱向切面的方式貫穿在整個架構中;
Spring 中兩個數據結構最核心:①?BeanDefinition,用于表示 Bean 的定義;②?BeanFactory,用于表示整個 IoC 容器。
3、spring framework的核心:IOC容器的實現
ioc容器概述
- 面向對象系統:對象封裝了數據和對數據的處理,對象的依賴關系主要體現在對數據和方法的依賴上。這種依賴關系可以通過把對象的依賴注入交給框架或者IOC容器來完成
- 依賴注入:依賴對象獲得被反轉了,由自身主動的獲取反轉到交給ioc容器來注入、獲取。新建對象、對象的引用賦值等操作交由容器來統一完成。從而將散落在不同代碼中的功能相同的部分集中成了容器的一部分,成了面向對象基礎設施的一部分。
- 對面向對象系統中的對象分2類:數據對象、處理數據的對象。后者不經常變化,很少涉及數據和狀態共享的問題,是系統中基礎的部分。同時這些對象間依賴關系也很穩定,這些特性非常適合由ioc容器來進行管理
IOC容器的設計與實現:
BeanFactory和ApplicationContext:
我們通常說的ioc容器實際上指的是一些功能各異的容器產品,各有特點
beanfactory:容器的基本功能;applicationcontext:應用上下文,作為容器的高級形態而存在,增加了很多面向框架的特性和適配。
beandefinition:抽象了對bean的定義,管理各種對象,是依賴翻轉模式中管理的對象依賴關系的數據抽象,是容器發揮作用的主要數據類型。計算機中,所有的功能都是建立在通過數據對現實進行抽象的基礎上的。
IOC容器的接口設計關系:
1、從接口BeanFactory---HierarchicalBeanFactory---ConfigurableBeanFactory,是一條主要的BeanFactory設計路徑。
2、第二條接口設計主線是以ApplicationContext應用上下文接口為核心的接口設計,從BeanFactory---ListableBeanFactory---ApplicationContext---WebApplicationContext(ConfigurableApplicationContext)。
3、具體的IoC容器都是在以上的接口體系下實現的,比如DefaultListableBeanFactory,實現了ConfigurableBeanFactory,從而成為一個簡單IoC容器的實現。其他的如XmlBeanFactory,都是在DefaultListableBeanFactory的基礎上做擴展,ApplicationContext也是如此。
4、BeanFactory是IoC容器最基本的接口,提供的是最基本的IoC容器的功能,比如getBean、containsBean等,其他高級IoC容器接口再在此基礎功能上進行擴展。
5、BeanFactory是一個對象工廠,管理Spring中所有的Bean,而FactoryBean是一個特殊的Bean。
IOC容器的創建步驟:
(1)創建IoC配置文件的抽象資源,包含了BeanDefinition的定義信息;
(2)創建一個BeanFactory;
(3)創建一個載入BeanDefinition的讀取器;
(4)從定義好的資源位置讀入配置信息。
核心屬性(Spring 循環依賴):
Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256):Bean 名稱到單例 Bean 的映射,用于存放完全初始化好的 Bean。可以理解成,這就是所謂的容器。這是一級緩存。
Map<String, Object> earlySingletonObjects = new HashMap<>(16):Bean 到“未成熟”單例 Bean 的映射。該 Bean 對象只是被創建出來,但是還沒有注入依賴。在容器解決循環依賴時,用于存儲中間狀態。這是二級緩存。
Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16):Bean 名稱到 Bean 的 ObjectFactory 對象的映射,存放 Bean 工廠對象。在容器解決循環依賴時,用于存儲中間狀態。這是三級緩存。
Bean 的獲取過程就類似計算機緩存的作用過程:先從一級獲取,失敗再從二級、三級里面獲取。org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)?方法
實際中最長使用的是ApplicationContext這個高級形態的IOC容器。他除了具備基本的beanfactory的功能,還集成了很多附加功能:
- 支持信息源,可以實現國際化。(實現MessageSource接口)
- 訪問資源。(實現ResourcePatternResolver接口,這個后面要講)
- 支持應用事件。(實現ApplicationEventPublisher接口)
- 在ApplicationContext中提供的附加服務
IOC容器初始化:
refresh()方法標志著ioc容器的正式啟動。具體包括beandefinition的resources定位、載入和注冊三個過程:
IOC容器的初始化分為三個過程實現:
- 第一個過程是Resource資源定位。這個Resouce指的是BeanDefinition的資源定位。這個過程就是容器找數據的過程,就像水桶裝水需要先找到水一樣。
- 第二個過程是BeanDefinition的載入過程。這個載入過程是把用戶定義好的Bean表示成Ioc容器內部的數據結構,而這個容器內部的數據結構就是BeanDefition。
- 第三個過程是向IOC容器注冊這些BeanDefinition的過程,這個過程就是將前面的BeanDefition保存到HashMap中的過程。
Spring容器創建之后,會調用它的refresh方法,refresh的時候會做很多事情:比如完成配置類的解析、各種BeanFactoryPostProcessor和BeanPostProcessor的注冊、國際化配置的初始化、web內置容器的構造等等。
?
總結
以上是生活随笔為你收集整理的spring技术内幕——深入解析spring架构与设计原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 近世代数--环--环的一些基本概念
- 下一篇: vue.js快速入门