技術(shù)分享!Spring 面試小抄
1. Spring 特點(diǎn)
Spring 主要有如下特點(diǎn):
輕量級(jí):Spring 是非侵入式,其中的對(duì)象不依賴 Spring 的特定類;
控制反轉(zhuǎn)(IoC):通過(guò) IoC,促進(jìn)了低耦合,一個(gè)對(duì)象依賴的其他對(duì)象通過(guò)被動(dòng)的方式傳遞進(jìn)來(lái),而不用該對(duì)象主動(dòng)創(chuàng)建或查找;
面向切面(AOP):支持面向切面編程,將應(yīng)用業(yè)務(wù)邏輯層和系統(tǒng)服務(wù)層分開(kāi);
容器:包含并管理應(yīng)用對(duì)象的配置以及生命周期,此時(shí) Spring 就相當(dāng)于一個(gè)容器;
框架集合:能將簡(jiǎn)單的組件進(jìn)行配置,組合成為更為復(fù)雜的應(yīng)用;在 Spring 中,應(yīng)用對(duì)象被聲明式地組合在一個(gè) XML 文件中;此外,Spring 也提供了事務(wù)管理、 持久化框架集成等基礎(chǔ)功能,將應(yīng)用邏輯的開(kāi)發(fā)留給開(kāi)發(fā)者;
2. Spring 核心組件

Spring 是一個(gè)分層架構(gòu),主要由如下 7 大模塊所構(gòu)成。Spring 模塊位于核心容器,定義了創(chuàng)建、配置和管理 Bean 的方式。
Spring Core:提供 Spring 框架基本功能,主要組件是 BeanFactory,是工廠模式的實(shí)現(xiàn),通過(guò) IOC 機(jī)制將應(yīng)用程序的配置和依賴性規(guī)范與實(shí)際的應(yīng)用程序代碼分開(kāi)。
Spring Context:一個(gè)配置文件,給 Spring 框架提供上下文信息,上下文包括 JNDI、EJB、電子郵件、國(guó)際化、校驗(yàn)和調(diào)度等企業(yè)服務(wù)。
Spring AOP :通過(guò)配置管理特性,Spring AOP 直接將 AOP(面向切面)功能集成到 Spring 框架。從而我們能夠十分方便的使用 Spring 框架來(lái)管理任何支持 AOP 的對(duì)象。模塊為基于 Spring 的應(yīng)用程序中的對(duì)象提供了事務(wù)管理服務(wù)。通過(guò)使用該組件,可以不依賴其他組件九江聲明性事務(wù)管理集成到應(yīng)用程序中。
Spring DAO:JDBC DAO 抽象層提供了有意義的異常層次結(jié)構(gòu),可以用來(lái)管理異常處理和不同數(shù)據(jù)庫(kù)供應(yīng)商拋出的錯(cuò)誤信息。異常層次結(jié)構(gòu)簡(jiǎn)化了錯(cuò)誤處理,而且極大降低了需要編寫(xiě)的異常代碼數(shù)量。Spring DAO 面向 JDBC 的異常遵從通用的 DAO 異常層次結(jié)構(gòu)。
Spring ORM:Spring 框架中插入了若干個(gè) ORM 框架,從而提供了 ORM 的對(duì)象關(guān)系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map,這些都遵從 Spring 的通用事務(wù)和 DAO 異常層次結(jié)構(gòu);
Spring Web:Web 上下文模塊建立在應(yīng)用程序上下文模塊之上,為基于 Web 的應(yīng)用程序提供了上下文,所以 Spring 框架支持與 Jakarta Structs 的集成。同時(shí)該模塊還簡(jiǎn)化了處理多部分請(qǐng)求以及請(qǐng)求參數(shù)綁定到域?qū)ο蟮墓ぷ鳌?/p>
Spring MVC:MVC 是一個(gè)全功能的構(gòu)建 Web 應(yīng)用的 MVC 實(shí)現(xiàn),可以通過(guò)策略接口對(duì) MVC 框架實(shí)現(xiàn)高度可配置。而且 MVC 還容納了 JSP、Velocity、Tiles 等視圖技術(shù)。
3. Spring 常用注解



4. IoC 原理
4.1 定義
Spring 通過(guò)一個(gè)配置文件來(lái)描述 Bean
之間的相互依賴關(guān)系,利用 Java 的反射功能來(lái)實(shí)例化 Bean
并建立 Bean
之間的依賴關(guān)系。Spring 的 IoC 容器在完成這些底層工作的基礎(chǔ)上,還提供 Bean
實(shí)例緩存、生命周期管理、Bean
實(shí)例代理、事件發(fā)布、資源裝載等高級(jí)服務(wù);
總結(jié)而言:IOC 負(fù)責(zé)創(chuàng)建對(duì)象、管理對(duì)象(通過(guò)依賴注入)、整合對(duì)象、配置對(duì)象以及管理對(duì)象的生命周期;
4.2 Spring 容器高層視圖

Spring 啟動(dòng)時(shí)先讀取
Bean
配置信息,并在 Spring 容器中生成一份對(duì)應(yīng)的Bean
配置注冊(cè)表;根據(jù)上一步中生成的
Bean
配置注冊(cè)表來(lái)實(shí)例化Bean
,并裝配好Bean
之間的依賴關(guān)系;將實(shí)例化后的
Bean
裝載到 Spring 容器中的Bean
緩存池中,供上層的應(yīng)用程序使用;
4.3 Spring Bean 的作用域及生命周期
4.3.1 作用域
Spring 中,用來(lái)組成應(yīng)用程序的主體以及由 Spring IoC 容器所管理的對(duì)象叫做 Bean。簡(jiǎn)而言之,Bean 就是由 IoC 容器來(lái)進(jìn)行初始化、裝配和管理的對(duì)象。
Bean 的作用域主要有如下幾種:
Singleton(單例)
作用域?yàn)?Singleton
,該模式在多線程下不安全,表明 IoC 容器中只會(huì)存在一個(gè)共享 Bean 實(shí)例,而且所有對(duì) Bean 的請(qǐng)求,主要 id
和該 Bean 定義相匹配,那么就會(huì)返回 Bean 的同一實(shí)例。Singleton
是單例模型,即在從創(chuàng)建容器的同時(shí)就會(huì)自動(dòng)創(chuàng)建一個(gè) Bean 的對(duì)象,無(wú)論是否使用,而且 每次獲取到的對(duì)象都是同一對(duì)象。
Prototype(原型):每次創(chuàng)建時(shí)使用
作用域?yàn)?Prototype
,表明一個(gè) Bean 定義對(duì)應(yīng)多個(gè)實(shí)例,該作用域中的 Bean 會(huì)導(dǎo)致在 每次對(duì)該 Bean 請(qǐng)求時(shí)均創(chuàng)建一個(gè)新的 Bean 實(shí)例。Prototype
是一個(gè)原型類型,在我們創(chuàng)建容器時(shí)并未實(shí)例化,而是當(dāng)我們獲取 Bean 時(shí)才去創(chuàng)建一個(gè)對(duì)象,而且每次獲取到的對(duì)象都不一樣。
Request:一次 request 一個(gè)實(shí)例
作用域?yàn)?Request
,表明在一次 HTTP
請(qǐng)求中,容器返回該 Bean 的同一個(gè)實(shí)例,即每個(gè) HTTP
請(qǐng)求均有各自的 Bean 實(shí)例,依據(jù)某個(gè) Bean 定義創(chuàng)建而成,只在基于 Web 的 Spring ApplicationContext 情形下有效。當(dāng)一次 HTTP
請(qǐng)求處理結(jié)束時(shí),該作用域中的 Bean 實(shí)例均被銷毀。
Session
作用域?yàn)?Session
,表明 在一個(gè) HTTP Session
中,容器返回該 Bean 的同一個(gè)實(shí)例,對(duì)不同的 Session
請(qǐng)求則創(chuàng)建新的實(shí)例,該 Bean
實(shí)例僅在當(dāng)前 Session
內(nèi)有效,只在基于 Web 的 Spring ApplicationContext 情形下有效。當(dāng)一個(gè) HTTP Session
被廢棄時(shí),在該作用域內(nèi)的 Bean 也將失效。

4.3.2 生命周期
Spring 對(duì) Bean 進(jìn)行實(shí)例化;
Spring 將值和 Bean 的引用注入到 Bean 對(duì)應(yīng)屬性中;
若 Bean 實(shí)現(xiàn)了 BeanNameAware 接口,則 Spring 將 Bean 的 ID 傳遞給 setBeanName() 方法;
若 Bean 實(shí)現(xiàn)了 BeanFactoryAware 接口,Spring 將調(diào)用
setBeanFactory()
方法,將 Bean 所在應(yīng)用引用傳入進(jìn)來(lái);若 Bean 實(shí)現(xiàn)了 ApplicationContextAware 接口,Spring 將調(diào)用
setApplicationContext()
方法,將 Bean 所在應(yīng)用的引用傳入進(jìn)來(lái);若 Bean 實(shí)現(xiàn)了 BeanPostProcessor 接口,Spring 將調(diào)用
post-ProcessBeforeInitalization()
方法;若 Bean 實(shí)現(xiàn)了
InitializingBean
接口,Spring 將調(diào)用他們的after-PropertiesSet()
方法,類似地,如果 Bean 使用init-method
聲明了初始化方法,則該方法也會(huì)被調(diào)用;若 Bean 實(shí)現(xiàn)了 BeanPostProcessor 接口,Spring 將調(diào)用他們的
post-ProcessAfterInitialization()
方法;此時(shí),Bean 已經(jīng)準(zhǔn)備就緒,我們就可以被應(yīng)用程序使用,他們將一直駐留在應(yīng)用上下文中,直到該應(yīng)用被銷毀;
若 Bean 實(shí)現(xiàn)了 DisposableBean 接口,Spring 將調(diào)用它的
destory()
接口方法;同樣,若 Bean 使用destroy-method
聲明了銷毀方法,該方法也將被調(diào)用;
4.4 Spring 依賴注入的四種方式
構(gòu)造器注入

靜態(tài)工廠注入
所謂靜態(tài)工廠就是通過(guò)調(diào)用靜態(tài)工廠的方法來(lái)獲取自己所需對(duì)象,而且為了方便 Spring 管理,我們不能通過(guò) “類.靜態(tài)方法()” 來(lái)獲取對(duì)象,而應(yīng)該通過(guò) Spring 注入的形式;

實(shí)例工廠
實(shí)例工廠表示獲取對(duì)象實(shí)例的方法不是靜態(tài)的,所以需要先?new
?工廠類,然后再調(diào)用普通的實(shí)例方法;

4.5 Spring 自動(dòng)裝配方式
要實(shí)現(xiàn)自動(dòng)裝配,主要從如下兩個(gè)角度來(lái)進(jìn)行實(shí)現(xiàn):
組件掃描(Component Scanning):Spring 會(huì)自動(dòng)發(fā)現(xiàn)應(yīng)用上下文中所創(chuàng)建的 Bean;
自動(dòng)裝配(Autowiring):Spring 自動(dòng)滿足 Bean 之間的依賴;
Spring 裝配包括 手動(dòng)轉(zhuǎn)配和自動(dòng)裝配,手動(dòng)裝配是通過(guò) XML
裝配、構(gòu)造方法、setter
方法等方式;
而自動(dòng)裝配有如下幾種,使得 Spring 容器通過(guò)自動(dòng)裝配方式來(lái)進(jìn)行依賴注入;


4.6 IoC 的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):組件之間的解耦,提高程序可維護(hù)性、靈活性;
缺點(diǎn):創(chuàng)建對(duì)象步驟復(fù)雜,有一定學(xué)習(xí)成本;利用反射創(chuàng)建對(duì)象,效率會(huì)降低;
5. AOP 原理
5.1 定義
即剖開(kāi)封裝的對(duì)象內(nèi)部,并將那些影響了多個(gè)類的公共行為封裝到一個(gè)可重用模塊,并將其命名為 Aspect
,即切面。所謂切面即 與業(yè)務(wù)無(wú)關(guān),但被業(yè)務(wù)模塊所公用的邏輯,便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,利于后續(xù)的可操作性和可維護(hù)性。
通過(guò)使用橫切,AOP 將軟件切分為:核心關(guān)注點(diǎn)和橫切關(guān)注點(diǎn)。業(yè)務(wù)處理的主要流程是核心關(guān)注點(diǎn),與橫切關(guān)注點(diǎn)關(guān)系不大。橫切關(guān)注點(diǎn)的特點(diǎn)是經(jīng)常發(fā)生在核心關(guān)注點(diǎn)的多處,且各處基本相似。AOP 的作用就在于 分離系統(tǒng)中的各種關(guān)注點(diǎn),將核心關(guān)注點(diǎn)和橫切關(guān)注點(diǎn)分離開(kāi)。
5.2 核心概念
5.3 AOP 的兩種代理方式
Spring 提供了兩種方式來(lái)生成代理對(duì)象:JDK Proxy 和 CGlib,默認(rèn)的策略是如果目標(biāo)類是接口,則使用 JDK 動(dòng)態(tài)代理技術(shù),否則使用 CGlib 來(lái)生成代理;
JDK 動(dòng)態(tài)接口代理
主要涉及 Proxy
和 InvocationHandler
,InvocationHandler
是一個(gè)接口,通過(guò)實(shí)現(xiàn)該接口定義橫切邏輯,并通過(guò)反射機(jī)制調(diào)用目標(biāo)類的代碼,動(dòng)態(tài)地將橫切邏輯與業(yè)務(wù)邏輯編制在一起。而 Proxy
則利用 InvocationHandler
動(dòng)態(tài)創(chuàng)建一個(gè)符合某一接口的實(shí)例,生成目標(biāo)類的代理對(duì)象;
CGlib 動(dòng)態(tài)代理
全稱 Code Generation Library
,是一個(gè)高性能高質(zhì)量的代碼生成類庫(kù),能在運(yùn)行期間擴(kuò)展 Java 類與實(shí)現(xiàn) Java 接口。 CGlib 封裝了 ASM,能在運(yùn)行期間動(dòng)態(tài)生成新的類。
JDK 動(dòng)態(tài)代理和 CGlib 動(dòng)態(tài)代理的區(qū)別
JDK 動(dòng)態(tài)代理只能為接口創(chuàng)建代理實(shí)例,而對(duì)于沒(méi)有通過(guò)接口定義業(yè)務(wù)方法的類,則需要通過(guò) CGlib 創(chuàng)建動(dòng)態(tài)代理;
5.4 切面的通知類型
前置通知(Before):目標(biāo)方法在被調(diào)用前調(diào)用通知;
后置通知(After):目標(biāo)方法完成后調(diào)用通知;
返回通知(After-returning):目標(biāo)方法成功執(zhí)行之后調(diào)用通知;
異常通知(After-throwing):目標(biāo)方法拋出異常后調(diào)用通知;
環(huán)繞通知(Around):在被通知的方法調(diào)用之前和調(diào)用之后執(zhí)行自定義的行為;
6. Spring MVC
6.1 什么是 MVC 框架?
MVC,全稱 Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫(xiě),是一種軟件設(shè)計(jì)典范。用一種業(yè)務(wù)邏輯、數(shù)據(jù)、界面顯示分離的方法組織代碼,將業(yè)務(wù)邏輯聚集到一個(gè)部件中,然后在改進(jìn)和個(gè)性化定制界面及用戶交互的同時(shí),不用重寫(xiě)業(yè)務(wù)邏輯;
采用 MVC 設(shè)計(jì)模式主要有如下好處:
通過(guò)分層設(shè)計(jì),實(shí)現(xiàn)了業(yè)務(wù)系統(tǒng)各組件之間的結(jié)構(gòu),有利于業(yè)務(wù)系統(tǒng)的可擴(kuò)展性和可維護(hù)性;
有利于系統(tǒng)的并行開(kāi)發(fā),提升開(kāi)發(fā)效率;
6.2 SpringMVC
6.2.1 定義
Spring MVC 是 Spring 框架的一個(gè)模塊,一個(gè)基于 MVC 的框架;
6.2.2 組件
DispatcherServlet
:核心組件,前端控制器,也叫中央控制器,由它來(lái)調(diào)度相關(guān)組件,用于接收請(qǐng)求、響應(yīng)結(jié)果,相當(dāng)于轉(zhuǎn)發(fā)器,有了DispatcherServlet
就減少了其他組件之間的耦合度;HandlerMapping
:處理器映射器,根據(jù) URL 路徑映射到不同的Handler
;HandlerAdapter
:處理器適配器,按照HandlerAdapter
的規(guī)則來(lái)執(zhí)行Handler
;Handler
:處理器,由我們自己根據(jù)業(yè)務(wù)進(jìn)行開(kāi)發(fā);ViewResolver
:視圖解析器,將邏輯視圖解析成具體的視圖;View
:一個(gè)接口,支持不同的視圖類型;
6.2.3 MVC 工作流程
瀏覽器發(fā)送請(qǐng)求,前端控制區(qū)
DispatcherServlet
攔截該請(qǐng)求;DispatcherServlet
攔截到請(qǐng)求后,對(duì)請(qǐng)求 URL 進(jìn)行解析,得到請(qǐng)求資源標(biāo)識(shí)符 URI,根據(jù) URI 調(diào)用HandlerMapping
后獲取對(duì)應(yīng)Handler
;DispatcherServlet
拿到Handler
之后,找到HandlerAdapter
,通過(guò)它來(lái)訪問(wèn)Handler
,并執(zhí)行處理器;執(zhí)行
Handler
的邏輯,返回一個(gè)ModelAndView
對(duì)象給DispatcherServlet
;然后
DispatcherServlet
請(qǐng)求ViewResolver
解析視圖,根據(jù)邏輯視圖名解析真正的View
;然后
ViewResolver
將解析后的View
返回給DispatcherServlet
,然后對(duì)View
進(jìn)行渲染;然后由
DispatcherServlet
響應(yīng)視圖給瀏覽器;
6.2.4 SpringMVC 的優(yōu)點(diǎn)
具有 Spring 的特性;
支持多種視圖;
配置方便,非侵入;
分層更加清晰,利于團(tuán)隊(duì)開(kāi)發(fā)的代碼維護(hù),以及可讀性好;
6.3 注解
6.3.1 注解原理
注解本質(zhì)上是一個(gè)集成了 Annotation
的特殊接口,其具體實(shí)現(xiàn)類是 Java 運(yùn)行時(shí)生成的動(dòng)態(tài)代理類。通過(guò)反射獲取注解時(shí),返回的是 Java 運(yùn)行時(shí)生成的動(dòng)態(tài)代理對(duì)象。通過(guò)代理對(duì)象調(diào)用自定義注解的方法,將最終調(diào)用 AnnotationInvocationHandler
的 invoke
方法,然后該方法從 memberValues
的 Map
中索引出對(duì)應(yīng)的值;
6.3.2 常用注解

了解更多,請(qǐng)點(diǎn)擊:https://www.bilibili.com/video/BV1JV411b742/
作者:村雨遙
鏈接:https://juejin.cn/post/6913458150016778254
來(lái)源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。