快來瞧瞧這份 Spring 面試小抄!


快來瞧瞧這份 Spring 面試小抄!

2021-01-06村上春香

微信搜一搜

村上遙

1. Spring 特點2. Spring 核心組件3. Spring 常用註解4. IoC 原理4.1 定義4.2 Spring 容器高層視圖4.3 Spring Bean 的作用域及生命周期4.4 Spring 依賴注入的四種方式4.5 Spring 自動裝配方式4.6 IoC 的優缺點5. AOP 原理5.1 定義5.2 核心概念5.3 AOP 的兩種代理方式5.4 切面的通知類型6. Spring MVC6.1 什麼是 MVC 框架?6.2 SpringMVC6.3 註解

1. Spring 特點

Spring 主要有如下特點:

輕量級:Spring 是非侵入式,其中的對象不依賴 Spring 的特定類;控制反轉(IoC):通過 IoC,促進了低耦合,一個對象依賴的其他對象通過被動的方式傳遞進來,而不用該對象主動創建或查找;面向切面(AOP):支持面向切面編程,將應用業務邏輯層和系統服務層分開;容器:包含並管理應用對象的配置以及生命周期,此時 Spring 就相當於一個容器;框架集合:能將簡單的組件進行配置,組合成爲更爲複雜的應用;在 Spring 中,應用對象被聲明式地組合在一個 XML 文件中;此外,Spring 也提供了事務管理、 持久化框架集成等基礎功能,將應用邏輯的開發留給開發者;2. Spring 核心組件

圖片源自網絡Spring 是一個分層架構,主要由如下 7 大模塊所構成。Spring 模塊位於核心容器,定義了創建、配置和管理 Bean 的方式。

Spring Core:提供 Spring 框架基本功能,主要組件是 BeanFactory,是工廠模式的實現,通過 IOC 機制將應用程式的配置和依賴性規範與實際的應用程式代碼分開。Spring Context:一個配置文件,給 Spring 框架提供上下文信息,上下文包括 JNDI、EJB、電子郵件、國際化、校驗和調度等企業服務。Spring AOP :通過配置管理特性,Spring AOP 直接將 AOP(面向切面)功能集成到 Spring 框架。從而我們能夠十分方便的使用 Spring 框架來管理任何支持 AOP 的對象。模塊爲基於 Spring 的應用程式中的對象提供了事務管理服務。通過使用該組件,可以不依賴其他組件九江聲明性事務管理集成到應用程式中。Spring DAO:JDBC DAO 抽象層提供了有意義的異常層次結構,可以用來管理異常處理和不同資料庫供應商拋出的錯誤信息。異常層次結構簡化了錯誤處理,而且極大降低了需要編寫的異常代碼數量。Spring DAO 面向 JDBC 的異常遵從通用的 DAO 異常層次結構。Spring ORM:Spring 框架中插入了若干個 ORM 框架,從而提供了 ORM 的對象關係工具,其中包括 JDO、Hibernate 和 iBatis SQL Map,這些都遵從 Spring 的通用事務和 DAO 異常層次結構;Spring Web:Web 上下文模塊建立在應用程式上下文模塊之上,爲基於 Web 的應用程式提供了上下文,所以 Spring 框架支持與 Jakarta Structs 的集成。同時該模塊還簡化了處理多部分請求以及請求參數綁定到域對象的工作。Spring MVC:MVC 是一個全功能的構建 Web 應用的 MVC 實現,可以通過策略接口對 MVC 框架實現高度可配置。而且 MVC 還容納了 JSP、Velocity、Tiles 等視圖技術。3. Spring 常用註解

4. IoC 原理

4.1 定義

Spring 通過一個配置文件來描述 Bean 之間的相互依賴關係,利用 Java 的反射功能來實例化 Bean 並建立 Bean 之間的依賴關係。Spring 的 IoC 容器在完成這些底層工作的基礎上,還提供 Bean 實例緩存、生命周期管理、Bean 實例代理、事件發布、資源裝載等高級服務;

總結而言:IOC 負責創建對象、管理對象(通過依賴注入)、整合對象、配置對象以及管理對象的生命周期;

4.2 Spring 容器高層視圖

Spring 啓動時先讀取 Bean 配置信息,並在 Spring 容器中生成一份對應的 Bean 配置註冊表;根據上一步中生成的 Bean 配置註冊表來實例化 Bean,並裝配好 Bean 之間的依賴關係;將實例化後的 Bean 裝載到 Spring 容器中的 Bean 緩存池中,供上層的應用程式使用;4.3 Spring Bean 的作用域及生命周期

4.3.1 作用域

Spring 中,用來組成應用程式的主體以及由 Spring IoC 容器所管理的對象叫做 Bean。簡而言之,Bean 就是由 IoC 容器來進行初始化、裝配和管理的對象。

Bean 的作用域主要有如下幾種:

Singleton(單例)作用域爲 Singleton,該模式在多線程下不安全,表明 IoC 容器中只會存在一個共享 Bean 實例,而且所有對 Bean 的請求,主要 id 和該 Bean 定義相匹配,那麼就會返回 Bean 的同一實例。Singleton 是單例模型,即在從創建容器的同時就會自動創建一個 Bean 的對象,無論是否使用,而且 每次獲取到的對象都是同一對象。

Prototype(原型):每次創建時使用作用域爲 Prototype,表明一個 Bean 定義對應多個實例,該作用域中的 Bean 會導致在 每次對該 Bean 請求時均創建一個新的 Bean 實例。Prototype 是一個原型類型,在我們創建容器時並未實例化,而是當我們獲取 Bean 時才去創建一個對象,而且每次獲取到的對象都不一樣。

Request:一次 request 一個實例作用域爲 Request,表明在一次 HTTP 請求中,容器返回該 Bean 的同一個實例,即每個 HTTP 請求均有各自的 Bean 實例,依據某個 Bean 定義創建而成,只在基於 Web 的 Spring ApplicationContext 情形下有效。當一次 HTTP 請求處理結束時,該作用域中的 Bean 實例均被銷毀。

Session作用域爲 Session ,表明 在一個 HTTP Session 中,容器返回該 Bean 的同一個實例,對不同的 Session 請求則創建新的實例,該 Bean 實例僅在當前 Session 內有效,只在基於 Web 的 Spring ApplicationContext 情形下有效。當一個 HTTP Session 被廢棄時,在該作用域內的 Bean 也將失效。

4.3.2 生命週期

Spring 對 Bean 進行實例化;Spring 將值和 Bean 的引用注入到 Bean 對應屬性中;若 Bean 實現了 BeanNameAware 接口,則 Spring 將 Bean 的 ID 傳遞給 setBeanName() 方法;若 Bean 實現了 BeanFactoryAware 接口,Spring 將調用 setBeanFactory() 方法,將 Bean 所在應用引用傳入進來;若 Bean 實現了 ApplicationContextAware 接口,Spring 將調用 setApplicationContext() 方法,將 Bean 所在應用的引用傳入進來;若 Bean 實現了 BeanPostProcessor 接口,Spring 將調用 post-ProcessBeforeInitalization() 方法;若 Bean 實現了 InitializingBean 接口,Spring 將調用他們的 after-PropertiesSet() 方法,類似地,如果 Bean 使用 init-method 聲明了初始化方法,則該方法也會被調用;若 Bean 實現了 BeanPostProcessor 接口,Spring 將調用他們的 post-ProcessAfterInitialization() 方法;此時,Bean 已經準備就緒,我們就可以被應用程式使用,他們將一直駐留在應用上下文中,直到該應用被銷毀;若 Bean 實現了 DisposableBean 接口,Spring 將調用它的 destory() 接口方法;同樣,若 Bean 使用 destroy-method 聲明了銷毀方法,該方法也將被調用;4.4 Spring 依賴注入的四種方式

構造器注入// 帶參,方便用構造器進行注入publicCatDaoImpl(String name){this.name = name;}setter方法注入publicclassId {privateint id; publicintgetId(){return id; } publicvoidsetId(int id){this.id = id; }}靜態工廠注入所謂靜態工廠就是通過調用靜態工廠的方法來獲取自己所需對象,而且爲了方便 Spring 管理,我們不能通過 「類.靜態方法()」 來獲取對象,而應該通過 Spring 注入的形式;

// 靜態工廠publicclassDaoFactory{publicstaticfinal FactoryDao getStaticFactoryDaoImpl(){returnnew StaticFacotryDaoImpl(); }}publicclassSpringAction{// 需要注入的對象private FactoryDao staticFactoryDao;// 注入對象的 set 方法publicvoidsetStaticFactoryDao(FactoryDao staticFactoryDao){this.staticFactoryDao = staticFactoryDao; }}實例工廠實例工廠表示獲取對象實例的方法不是靜態的,所以需要先 new 工廠類,然後再調用普通的實例方法;

//實例工廠publicclassDaoFactory {public FactoryDao getFactoryDaoImpl(){returnnew FactoryDaoImpl(); }} publicclassSpringAction {//注入對象private FactoryDao factoryDao; publicvoidsetFactoryDao(FactoryDao factoryDao){this.factoryDao = factoryDao; }}4.5 Spring 自動裝配方式

要實現自動裝配,主要從如下兩個角度來進行實現:

組件掃描(Component Scanning):Spring 會自動發現應用上下文中所創建的 Bean;自動裝配(Autowiring):Spring 自動滿足 Bean 之間的依賴;Spring 裝配包括 手動轉配和自動裝配,手動裝配是通過 XML 裝配、構造方法、setter 方法等方式;

而自動裝配有如下幾種,使得 Spring 容器通過自動裝配方式來進行依賴注入;

4.6 IoC 的優缺點

優點:組件之間的解耦,提高程序可維護性、靈活性;缺點:創建對象步驟複雜,有一定學習成本;利用反射創建對象,效率會降低;5. AOP 原理

5.1 定義

即剖開封裝的對象內部,並將那些影響了多個類的公共行爲封裝到一個可重用模塊,並將其命名爲 Aspect,即切面。所謂切面即 與業務無關,但被業務模塊所公用的邏輯,便於減少系統的重複代碼,降低模塊間的耦合度,利於後續的可操作性和可維護性。

通過使用橫切,AOP 將軟體切分爲:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與橫切關注點關係不大。橫切關注點的特點是經常發生在核心關注點的多處,且各處基本相似。AOP 的作用就在於 分離系統中的各種關注點,將核心關注點和橫切關注點分離開。

5.2 核心概念

5.3 AOP 的兩種代理方式

Spring 提供了兩種方式來生成代理對象:JDK Proxy 和 CGlib,默認的策略是如果目標類是接口,則使用 JDK 動態代理技術,否則使用 CGlib 來生成代理;

JDK 動態接口代理主要涉及 Proxy 和 InvocationHandler,InvocationHandler 是一個接口,通過實現該接口定義橫切邏輯,並通過反射機制調用目標類的代碼,動態地將橫切邏輯與業務邏輯編制在一起。而 Proxy 則利用 InvocationHandler 動態創建一個符合某一接口的實例,生成目標類的代理對象;

CGlib 動態代理全稱 Code Generation Library,是一個高性能高質量的代碼生成類庫,能在運行期間擴展 Java 類與實現 Java 接口。 CGlib 封裝了 ASM,能在運行期間動態生成新的類。

JDK 動態代理和 CGlib 動態代理的區別JDK 動態代理只能爲接口創建代理實例,而對於沒有通過接口定義業務方法的類,則需要通過 CGlib 創建動態代理;

5.4 切面的通知類型

前置通知(Before):目標方法在被調用前調用通知;後置通知(After):目標方法完成後調用通知;返回通知(After-returning):目標方法成功執行之後調用通知;異常通知(After-throwing):目標方法拋出異常後調用通知;環繞通知(Around):在被通知的方法調用之前和調用之後執行自定義的行爲;6. Spring MVC

6.1 什麼是 MVC 框架?

MVC,全稱 Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫,是一種軟體設計典範。用一種業務邏輯、數據、界面顯示分離的方法組織代碼,將業務邏輯聚集到一個部件中,然後在改進和個性化定製界面及用戶交互的同時,不用重寫業務邏輯;

採用 MVC 設計模式主要有如下好處:

通過分層設計,實現了業務系統各組件之間的結構,有利於業務系統的可擴展性和可維護性;有利於系統的並行開發,提升開發效率;6.2 SpringMVC

6.2.1 定義

Spring MVC 是 Spring 框架的一個模塊,一個基於 MVC 的框架;

6.2.2 組件

DispatcherServlet:核心組件,前端控制器,也叫中央控制器,由它來調度相關組件,用於接收請求、響應結果,相當於轉發器,有了 DispatcherServlet 就減少了其他組件之間的耦合度;HandlerMapping:處理器映射器,根據 URL 路徑映射到不同的 Handler;HandlerAdapter:處理器適配器,按照 HandlerAdapter 的規則來執行 Handler;Handler:處理器,由我們自己根據業務進行開發;ViewResolver:視圖解析器,將邏輯視圖解析成具體的視圖;View:一個接口,支持不同的視圖類型;6.2.3 MVC 工作流程

瀏覽器發送請求,前端控制區 DispatcherServlet 攔截該請求;DispatcherServlet 攔截到請求後,對請求 URL 進行解析,得到請求資源標識符 URI,根據 URI 調用 HandlerMapping 後獲取對應 Handler;DispatcherServlet 拿到 Handler 之後,找到 HandlerAdapter ,通過它來訪問 Handler,並執行處理器;執行 Handler 的邏輯,返回一個 ModelAndView 對象給 DispatcherServlet;然後 DispatcherServlet 請求 ViewResolver 解析視圖,根據邏輯視圖名解析真正的 View;然後 ViewResolver 將解析後的 View 返回給 DispatcherServlet,然後對 View 進行渲染;然後由 DispatcherServlet 響應視圖給瀏覽器;6.2.4 SpringMVC 的優點

具有 Spring 的特性;支持多種視圖;配置方便,非侵入;分層更加清晰,利於團隊開發的代碼維護,以及可讀性好;6.3 註解

6.3.1 註解原理

註解本質上是一個集成了 Annotation 的特殊接口,其具體實現類是 Java 運行時生成的動態代理類。通過反射獲取註解時,返回的是 Java 運行時生成的動態代理對象。通過代理對象調用自定義註解的方法,將最終調用 AnnotationInvocationHandler 的 invoke 方法,然後該方法從 memberValues 的 Map 中索引出對應的值;

6.3.2 常用註解