spring總結(jié)番电,從底層源碼角度概括岗屏,工作三四年都不一定明白

spring總結(jié)


1、什么是Spring框架漱办,Spring框架主要包含哪些模塊

Spring是一個開源框架这刷,Spring是一個輕量級的Java 開發(fā)框架。它是為了解決企業(yè)應用開發(fā)的復雜性而創(chuàng)建的娩井。框架的主要優(yōu)勢之一就是其分層架構(gòu),分層架構(gòu)允許使用者選擇使用哪一個組件淋叶,同時為 J2EE 應用程序開發(fā)提供集成的框架码俩。Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。然而扬霜,Spring的用途不僅限于服務器端的開發(fā)定鸟。從簡單性、可測試性和松耦合的角度而言著瓶,任何Java應用都可以從Spring中受益联予。Spring的核心是控制反轉(zhuǎn)(IoC)和面向切面(AOP)。簡單來說材原,Spring是一個分層的full-stack(一站式)輕量級開源框架沸久。(需要這份資料可文末領取)

主要包含的模塊:

2余蟹、Spring框架的優(yōu)勢

1卷胯、Spring通過DI、AOP和消除樣板式代碼來簡化企業(yè)級Java開發(fā)

2威酒、Spring框架之外還存在一個構(gòu)建在核心框架之上的龐大生態(tài)圈窑睁,它將Spring擴展到不同的領域,如Web服務兼搏、REST卵慰、移動開發(fā)以及NoSQL

3、低侵入式設計佛呻,代碼的污染極低

4裳朋、獨立于各種應用服務器,基于Spring框架的應用,可以真正實現(xiàn)Write Once,Run Anywhere的承諾

5鲤嫡、Spring的IoC容器降低了業(yè)務對象替換的復雜性送挑,提高了組件之間的解耦

6、Spring的AOP允許將一些通用任務如安全暖眼、事務惕耕、日志等進行集中式處理,從而提供了更好的復用

7诫肠、Spring的ORM和DAO提供了與第三方持久層框架的的良好整合司澎,并簡化了底層的數(shù)據(jù)庫訪問

8、Spring的高度開放性栋豫,并不強制應用完全依賴于Spring挤安,開發(fā)者可自由選用Spring框架的部分或全部

3、IOC和DI是什么丧鸯?

控制反轉(zhuǎn)是就是應用本身不負責依賴對象的創(chuàng)建和維護,依賴對象的創(chuàng)建及維護是由外部容器負責的,這樣控制權(quán)就有應用轉(zhuǎn)移到了外部容器,控制權(quán)的轉(zhuǎn)移就是控制反轉(zhuǎn)蛤铜。

依賴注入是指:在程序運行期間,由外部容器動態(tài)地將依賴對象注入到組件中如:一般,通過構(gòu)造函數(shù)注入或者setter注入丛肢。

4围肥、描述下Spring IOC容器的初始化過程

spring核心接口

BeanFactory 頂層核心接口,規(guī)范子工廠蜂怎,生產(chǎn)bean BeanDefinition 封裝了一切用來生產(chǎn)bean方式

spring ioc穆刻、bean生命周期

spring 擴展點

就是我們程序員自己根據(jù)需要去實現(xiàn)的spring底層的擴展

BeanFactoryPostProcessor bean工廠后置處理器(可以用來修改bean定義的)

9個Bean的后置處理器

InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation

SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors

MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition

SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference

InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation

InstantiationAwareBeanPostProcessor.postProcessPropertyValues

BeanPostProcessor.postProcessBeforeInitialization

BeanPostProcessor.postProcessAfterInitialization

DestructionAwareBeanPostProcessor.requiresDestruction

怎么看源碼?

1.把spring的項目源碼直接下過來編譯派敷。

new springApplication()

解析xml配置文件路徑

(AbstractApplicationContext#obtainFreshBeanFactory)

3.創(chuàng)建Bean工廠

4.加載bean定義到BeanDefinitionMap

5.調(diào)用了bean工廠的后置處理器:invokeBeanFactoryPostProcessors()

>org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization

>org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

6.判斷是否符合生產(chǎn)標準(是不是抽象蛹批、懶加載、單例) >org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

7.真正的生產(chǎn)Bean, 去單例池中獲取看是否已經(jīng)創(chuàng)建篮愉,如果已經(jīng)創(chuàng)建則直接返回腐芍,如果單例池沒有就需要重新創(chuàng)建(為了解決循環(huán)依賴,將當前Bean加入到正在創(chuàng)建的標識中singletonsCurrentlyInCreation) >org.springframework.beans.factory.support.AbstractBeanFactory#createBean

8.可以使用Bean的后置處理器直接返回自定義的Bean實例

>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

9.調(diào)用doCreateBean開始真正創(chuàng)建Bean >org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance

10.實例化Bean(通過工廠方法试躏、Supplier猪勇、Bean后置處理器:

SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors,BeanDefinition的 ConstructorArgumentValues) 默認調(diào)用無參構(gòu)造函數(shù)來實例化

>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

11.注入屬性值

>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

12.初始化Bean 調(diào)用Awea 調(diào)用@PostConstrut Aop的動態(tài)代理也是在初始完進行生成的

13.最終加入到單例池中

5颠蕴、BeanFactory 和 FactoryBean的區(qū)別泣刹?

BeanFactory是個Factory,也就是IOC容器或?qū)ο蠊S犀被,在Spring中椅您,所有的Bean都是由BeanFactory(也就是IOC容器)來進行管理的,提供了實例化對象和拿對象的功能寡键。

使用場景:

從Ioc容器中獲取Bean(byName or byType)

檢索Ioc容器中是否包含指定的Bean

判斷Bean是否為單例

FactoryBean是個Bean掀泳,這個Bean不是簡單的Bean,而是一個能生產(chǎn)或者修飾對象生成的工廠Bean,它的實現(xiàn)與設計模式中的工廠模式和修飾器模式類似。

facotryBean不是在spring上文加載的時候創(chuàng)建的员舵, 在getBean的時候創(chuàng)建的使用場景

ProxyFactoryBean

6脑沿、BeanFactory和ApplicationContext的異同

BeanFactory:spring 頂層核心接口,用來生產(chǎn)bean的.

相同:

Spring提供了兩種不同的IOC 容器马僻,一個是BeanFactory庄拇,另外一個是ApplicationContext,它們都是 Java interface韭邓,ApplicationContext繼承于BeanFactory(ApplicationContext繼承ListableBeanFactory措近。

它們都可以用來配置XML屬性,也支持屬性的自動注入仍秤。

BeanFactory 和 ApplicationContext 都提供了一種方式熄诡,使用getBean("bean name")獲取bean。

不同:

BeanFactory不支持國際化诗力,即i18n,但ApplicationContext提供了對它的支持我抠。

BeanFactory與ApplicationContext之間的另一個區(qū)別是能夠?qū)⑹录l(fā)布到注冊為監(jiān)聽器的bean苇本。

BeanFactory 的一個核心實現(xiàn)是XMLBeanFactory 而ApplicationContext 的一個核心實現(xiàn)是ClassPathXmlApplicationContext,Web容器的環(huán)境我們使用WebApplicationContext并且增加了 getServletContext 方法菜拓。

如果使用自動注入并使用BeanFactory瓣窄,則需要使用API注冊AutoWiredBeanPostProcessor,如果使用ApplicationContext纳鼎,則可以使用XML進行配置俺夕。

簡而言之,BeanFactory提供基本的IOC和DI功能贱鄙,而ApplicationContext提供高級功能劝贸,BeanFactory可用于測試和非生產(chǎn)使用,但ApplicationContext是功能更豐富的容器實現(xiàn)逗宁,應該優(yōu)于BeanFactory

7映九、Spring Bean 的生命周期?

總結(jié):

(1)實例化Bean:

對于BeanFactory容器瞎颗,當客戶向容器請求一個尚未初始化的bean時件甥,或初始化bean的時候需要注入另一個尚未初始化的依賴時,容器就會調(diào)用createBean進行實例化哼拔。對于ApplicationContext容器引有,當容器啟動結(jié)束后,通過獲取BeanDefinition對象中的信息倦逐,實例化所有的bean譬正。

(2)設置對象屬性(依賴注入):

實例化后的對象被封裝在BeanWrapper對象中,緊接著,Spring根據(jù)BeanDefinition中的信息以及通過BeanWrapper提供的設置屬性的接口完成依賴注入导帝。

(3)處理Aware接口:

接著守谓,Spring會檢測該對象是否實現(xiàn)了xxxAware接口,并將相關(guān)的xxxAware實例注入給Bean:

①如果這個Bean已經(jīng)實現(xiàn)了BeanNameAware接口您单,會調(diào)用它實現(xiàn)的setBeanName(String beanId)方法斋荞,此處傳遞的就是Spring配置文件中Bean的id值;

②如果這個Bean已經(jīng)實現(xiàn)了BeanFactoryAware接口虐秦,會調(diào)用它實現(xiàn)的setBeanFactory()方法平酿,傳遞的是Spring工廠自身。

③如果這個Bean已經(jīng)實現(xiàn)了ApplicationContextAware接口悦陋,會調(diào)用setApplicationContext(ApplicationContext)方法蜈彼,傳入Spring上下文;

(4)BeanPostProcessor:

如果想對Bean進行一些自定義的處理俺驶,那么可以讓Bean實現(xiàn)了BeanPostProcessor接口幸逆,那將會調(diào)用 postProcessBeforeInitialization(Object obj, String s)方法。(5)InitializingBean 與 init-method:

如果Bean在Spring配置文件中配置了 init-method 屬性暮现,則會自動調(diào)用其配置的初始化方法还绘。

(6)如果這個Bean實現(xiàn)了BeanPostProcessor接口,將會調(diào)用postProcessAfterInitialization(Object obj, String s)方法栖袋;由于這個方法是在Bean初始化結(jié)束時調(diào)用的拍顷,所以可以被應用于內(nèi)存或緩存技術(shù);以上幾個步驟完成后塘幅,Bean就已經(jīng)被正確創(chuàng)建了昔案,之后就可以使用這個Bean了。

(7)DisposableBean:

當Bean不再需要時电媳,會經(jīng)過清理階段踏揣,如果Bean實現(xiàn)了DisposableBean這個接口,會調(diào)用其實現(xiàn)的destroy()方法匆背;

(8)destroy-method:

最后呼伸,如果這個Bean的Spring配置中配置了destroy-method屬性,會自動調(diào)用其配置的銷毀方法钝尸。

8括享、Spring AOP的實現(xiàn)原理?

Spring AOP使用的動態(tài)代理珍促,所謂的動態(tài)代理就是說AOP框架不會去修改字節(jié)碼铃辖,而是在內(nèi)存中臨時為方法生成一個AOP對象,這個AOP對象包含了目標對象的全部方法猪叙,并且在特定的切點做了增強處理娇斩,并回調(diào)原對象的方法仁卷。

Spring AOP中的動態(tài)代理主要有兩種方式,JDK動態(tài)代理和CGLIB動態(tài)代理犬第。JDK動態(tài)代理通過反射來接收被代理的類锦积,并且要求被代理的類必須實現(xiàn)一個接口。JDK動態(tài)代理的核心是InvocationHandler接口和Proxy類歉嗓。

如果目標類沒有實現(xiàn)接口丰介,那么Spring AOP會選擇使用CGLIB來動態(tài)代理目標類。CGLIB(Code Generation Library)鉴分,是一個代碼生成的類庫哮幢,可以在運行時動態(tài)的生成某個類的子類,注意志珍,CGLIB是通過繼承的方式做的動態(tài)代理橙垢,因此如果某個類被標記為final,那么它是無法使用CGLIB做動態(tài)代理的伦糯。

9柜某、聲明式事務的優(yōu)缺點:

優(yōu)點:不需要在業(yè)務邏輯代碼中編寫事務相關(guān)代碼,只需要在配置文件配置或使用注解(@Transaction)舔株,這種方式?jīng)]有侵入性莺琳。

缺點:聲明式事務的最細粒度作用于方法上,如果像代碼塊也有事務需求载慈,只能變通下,將代碼塊變?yōu)榉椒ā?/p>

10珍手、Spring 的不同事務傳播行為有哪些办铡,干什么用的?

11琳要、Spring 中用到了那些設計模式寡具?

代理模式—在AOP中被用的比較多。

單例模式—在spring配置文件中定義的bean默認為單例模式稚补。

模板方法—用來解決代碼重復的問題童叠。比如. RestTemplate, JmsTemplate, JpaTemplate。

工廠模式—BeanFactory用來創(chuàng)建對象的實例课幕。

適配器--spring aop

裝飾器--spring data hashmapper

觀察者-- spring 事件驅(qū)動模型

回調(diào)--Spring Aware回調(diào)接口

12厦坛、Spring如何解決循環(huán)依賴?

https://juejin.cn/post/7085607089044717599

13乍惊、bean的作用域

(1)singleton:默認杜秸,每個容器中只有一個bean的實例,單例的模式由BeanFactory自身來維護润绎。

(2)prototype:為每一個bean請求提供一個實例撬碟。

(3)request:為每一個網(wǎng)絡請求創(chuàng)建一個實例诞挨,在請求完成以后,bean會失效并被垃圾回收器回收呢蛤。

(4)session:與request范圍類似惶傻,確保每個session中有一個bean的實例,在session過期后其障,bean會隨之失效银室。

14、Spring框架中有哪些不同類型的事件

(1)上下文更新事件(ContextRefreshedEvent):在調(diào)用ConfigurableApplicationContext 接口中的refresh()方法時被觸發(fā)静秆。

(2)上下文開始事件(ContextStartedEvent):當容器調(diào)用ConfigurableApplicationContext的Start()方法開始/重新開始容器時觸發(fā)該事件粮揉。

(3)上下文停止事件(ContextStoppedEvent):當容器調(diào)用ConfigurableApplicationContext的Stop()方法停止容器時觸發(fā)該事件。

(4)上下文關(guān)閉事件(ContextClosedEvent):當ApplicationContext被關(guān)閉時觸發(fā)該事件抚笔。容器被關(guān)閉時扶认,其管理的所有單例Bean都被銷毀。

(5)請求處理事件(RequestHandledEvent):在Web應用中殊橙,當一個http請求(request)結(jié)束觸發(fā)該事件辐宾。

15、Spring通知有哪些類型

(1)前置通知(Before advice):在某連接點(join point)之前執(zhí)行的通知膨蛮,但這個通知不能阻止連接點前的執(zhí)行(除非它拋出一個異常)叠纹。

(2)返回后通知(After returning advice):在某連接點(join point)正常完成后執(zhí)行的通知:例如,一個方法沒有拋出任何異常敞葛,正常返回誉察。

(3)拋出異常后通知(After throwing advice):在方法拋出異常退出時執(zhí)行的通知。

(4)后通知(After (finally) advice):當某連接點退出的時候執(zhí)行的通知(不論是正常返回還是異常退出)惹谐。(5)環(huán)繞通知(Around Advice):包圍一個連接點(join point)的通知持偏,如方法調(diào)用。這是最強大的一種通知類型氨肌。環(huán)繞通知可以在方法調(diào)用前后完成自定義的行為鸿秆。它也會選擇是否繼續(xù)執(zhí)行連接點或直接返回它們自己的返回值或拋出異常來結(jié)束執(zhí)行。環(huán)繞通知是最常用的一種通知類型怎囚。

16卿叽、Spring的自動裝配

在spring中,對象無需自己查找或創(chuàng)建與其關(guān)聯(lián)的其他對象恳守,由容器負責把需要相互協(xié)作的對象引用賦予各個對象考婴,使用autowire來配置自動裝載模式。

在Spring框架xml配置中共有5種自動裝配:

(1)no:默認的方式是不進行自動裝配的井誉,通過手工設置ref屬性來進行裝配bean蕉扮。

(2)byName:通過bean的名稱進行自動裝配,如果一個bean的 property 與另一bean 的name 相同颗圣,就進行自動裝配喳钟。

(3)byType:通過參數(shù)的數(shù)據(jù)類型進行自動裝配屁使。

(4)constructor:利用構(gòu)造函數(shù)進行裝配,并且構(gòu)造函數(shù)的參數(shù)通過byType進行裝配奔则。

(5)autodetect:自動探測蛮寂,如果有構(gòu)造方法,通過 construct的方式自動裝配易茬,否則使用 byType的方式自動裝配酬蹋。

基于注解的方式:

使用@Autowired注解來自動裝配指定的bean。在使用@Autowired注解之前需要在Spring配置文件進行配置抽莱, <context:annotation-config />范抓。在啟動spring IoC時,容器自動裝載了一個AutowiredAnnotationBeanPostProcessor后置處理器食铐,當容器掃描到@Autowied匕垫、@Resource或@Inject時,就會在IoC容器自動查找需要的bean虐呻,并裝配給該對象的屬性象泵。在使用@Autowired時,首先在容器中查詢對應類型的bean:

如果查詢結(jié)果剛好為一個斟叼,就將該bean裝配給@Autowired指定的數(shù)據(jù)偶惠;如果查詢的結(jié)果不止一個,那么@Autowired會根據(jù)名稱來查找朗涩;

如果上述查找的結(jié)果為空忽孽,那么會拋出異常。解決方法時谢床,使用required=false扒腕。

@Autowired可用于:構(gòu)造函數(shù)、成員變量萤悴、Setter方法

注:@Autowired和@Resource之間的區(qū)別

@Autowired默認是按照類型裝配注入的,默認情況下它要求依賴對象必須存在(可以設置它required屬性為false)皆的。

@Resource默認是按照名稱來裝配注入的覆履,只有當找不到與名稱匹配的bean才會按照類型來裝配注入。

最后

文章寫的如有不對之處還望指正费薄,如有需要文章所示資料可“點贊 收藏 關(guān)注”后私信小編領取硝全,最后祝大家好好學習,天天向上楞抡!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伟众,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子召廷,更是在濱河造成了極大的恐慌凳厢,老刑警劉巖账胧,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異先紫,居然都是意外死亡治泥,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門遮精,熙熙樓的掌柜王于貴愁眉苦臉地迎上來居夹,“玉大人,你說我怎么就攤上這事本冲∽贾” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵檬洞,是天一觀的道長狸膏。 經(jīng)常有香客問我,道長疮胖,這世上最難降的妖魔是什么环戈? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮澎灸,結(jié)果婚禮上院塞,老公的妹妹穿的比我還像新娘。我一直安慰自己性昭,他們只是感情好拦止,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著糜颠,像睡著了一般汹族。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上其兴,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天顶瞒,我揣著相機與錄音,去河邊找鬼元旬。 笑死榴徐,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的匀归。 我是一名探鬼主播坑资,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼穆端!你這毒婦竟也來了袱贮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤体啰,失蹤者是張志新(化名)和其女友劉穎攒巍,沒想到半個月后嗽仪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡窑业,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年钦幔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片常柄。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡鲤氢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出西潘,到底是詐尸還是另有隱情卷玉,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布喷市,位于F島的核電站相种,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏品姓。R本人自食惡果不足惜寝并,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望腹备。 院中可真熱鬧衬潦,春花似錦、人聲如沸植酥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽友驮。三九已至漂羊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卸留,已是汗流浹背走越。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留耻瑟,地道東北人买喧。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像匆赃,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子今缚,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容