Spring面試題總結的很全面,附帶超詳細答案

一、什麼是Spring?

Spring是一個開源的Java EE開發框架。Spring框架的核心功能能夠應用在任何Java應用程序中,但對Java EE平臺上的Web應用程序有更好的擴展性。Spring框架的目標是使得Java EE應用程序的開發更加簡捷,經過使用POJO爲基礎的編程模型促進良好的編程風格。前端

二、Spring有哪些優勢?

輕量級:Spring在大小和透明性方面絕對屬於輕量級的,基礎版本的Spring框架大約只有2MB。java

控制反轉(IOC):Spring使用控制反轉技術實現了鬆耦合。依賴被注入到對象,而不是建立或尋找依賴對象。程序員

面向切面編程(AOP): Spring支持面向切面編程,同時把應用的業務邏輯與系統的服務分離開來。web

容器:Spring包含並管理應用程序對象的配置及生命週期。spring

MVC框架:Spring的web框架是一個設計優良的web MVC框架,很好的取代了一些web框架。數據庫

事務管理:Spring對下至本地業務上至全局業務(JAT)提供了統一的事務管理接口。編程

異常處理:Spring提供一個方便的API將特定技術的異常(由JDBC, Hibernate, 或JDO拋出)轉化爲一致的、Unchecked異常。數組

三、Spring 事務實現方式

  • 編程式事務管理:這意味着你能夠經過編程的方式管理事務,這種方式帶來了很大的靈活性,但很難維護。緩存

  • 聲明式事務管理:這種方式意味着你能夠將事務管理和業務代碼分離。你只須要經過註解或者XML配置管理事務。網絡

四、Spring框架的事務管理有哪些優勢

  • 它爲不一樣的事務API(如JTA, JDBC, Hibernate, JPA, 和JDO)提供了統一的編程模型。

  • 它爲編程式事務管理提供了一個簡單的API而非一系列複雜的事務API(如JTA).

  • 它支持聲明式事務管理。

  • 它能夠和Spring 的多種數據訪問技術很好的融合。

五、spring事務定義的傳播規則

  • PROPAGATION_REQUIRED: 支持當前事務,若是當前沒有事務,就新建一個事務。這是最多見的選擇。

  • PROPAGATION_SUPPORTS: 支持當前事務,若是當前沒有事務,就以非事務方式執行。

  • PROPAGATION_MANDATORY: 支持當前事務,若是當前沒有事務,就拋出異常。

  • PROPAGATION_REQUIRES_NEW: 新建事務,若是當前存在事務,把當前事務掛起。

  • PROPAGATION_NOT_SUPPORTED: 以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。

  • PROPAGATION_NEVER: 以非事務方式執行,若是當前存在事務,則拋出異常。

  • PROPAGATION_NESTED: 若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則進行與PROPAGATION_REQUIRED相似的操做。

六、Spring 事務底層原理

  • 劃分處理單元——IoC

因爲spring解決的問題是對單個數據庫進行局部事務處理的,具體的實現首先用spring中的IoC劃分了事務處理單元。而且將對事務的各類配置放到了ioc容器中(設置事務管理器,設置事務的傳播特性及隔離機制)。

  • AOP攔截須要進行事務處理的類

Spring事務處理模塊是經過AOP功能來實現聲明式事務處理的,具體操做(好比事務實行的配置和讀取,事務對象的抽象),用TransactionProxyFactoryBean接口來使用AOP功能,生成proxy代理對象,經過TransactionInterceptor完成對代理方法的攔截,將事務處理的功能編織到攔截的方法中。讀取ioc容器事務配置屬性,轉化爲spring事務處理須要的內部數據結構(TransactionAttributeSourceAdvisor),轉化爲TransactionAttribute表示的數據對象。

  • 對事務處理實現(事務的生成、提交、回滾、掛起)

spring委託給具體的事務處理器實現。實現了一個抽象和適配。適配的具體事務處理器:DataSource數據源支持、hibernate數據源事務處理支持、JDO數據源事務處理支持,JPA、JTA數據源事務處理支持。這些支持都是經過設計PlatformTransactionManager、AbstractPlatforTransaction一系列事務處理的支持。 爲經常使用數據源支持提供了一系列的TransactionManager。

  • 結合

PlatformTransactionManager實現了TransactionInterception接口,讓其與TransactionProxyFactoryBean結合起來,造成一個Spring聲明式事務處理的設計體系。

七、Spring MVC 運行流程

第一步:發起請求到前端控制器(DispatcherServlet)

第二步:前端控制器請求HandlerMapping查找 Handler( 能夠根據xml配置、註解進行查找)

第三步:處理器映射器HandlerMapping向前端控制器返回Handler

第四步:前端控制器調用處理器適配器去執行Handler

第五步:處理器適配器去執行Handler

第六步:Handler執行完成給適配器返回ModelAndView

第七步:處理器適配器向前端控制器返回ModelAndView(ModelAndView是springmvc框架的一個底層對象,包括Model和view)

第八步:前端控制器請求視圖解析器去進行視圖解析(根據邏輯視圖名解析成真正的視圖(jsp))

第九步:視圖解析器向前端控制器返回View

第十步:前端控制器進行視圖渲染( 視圖渲染將模型數據(在ModelAndView對象中)填充到request域)

第十一步:前端控制器向用戶響應結果

八、BeanFactory和ApplicationContext有什麼區別?

ApplicationContext提供了一種解決文檔信息的方法,一種加載文件資源的方式(如圖片),他們能夠向監聽他們的beans發送消息。另外,容器或者容器中beans的操做,這些必須以bean工廠的編程方式處理的操做能夠在應用上下文中以聲明的方式處理。應用上下文實現了MessageSource,該接口用於獲取本地消息,實際的實現是可選的。

相同點:二者都是經過xml配置文件加載bean,ApplicationContext和BeanFacotry相比,提供了更多的擴展功能。

不一樣點:BeanFactory是延遲加載,若是Bean的某一個屬性沒有注入,BeanFacotry加載後,直至第一次使用調用getBean方法纔會拋出異常;而ApplicationContext則在初始化自身是檢驗,這樣有利於檢查所依賴屬性是否注入;因此一般狀況下咱們選擇使用ApplicationContext。

九、什麼是Spring Beans?

Spring Beans是構成Spring應用核心的Java對象。這些對象由Spring IOC容器實例化、組裝、管理。這些對象經過容器中配置的元數據建立,例如,使用XML文件中定義的建立。

在Spring中建立的beans都是單例的beans。在bean標籤中有一個屬性爲」singleton」,若是設爲true,該bean是單例的,若是設爲false,該bean是原型bean。Singleton屬性默認設置爲true。所以,spring框架中全部的bean都默認爲單例bean。

十、說一下Spring中支持的bean做用域

Spring框架支持以下五種不一樣的做用域:

  • singleton:在Spring IOC容器中僅存在一個Bean實例,Bean以單實例的方式存在。

  • prototype:一個bean能夠定義多個實例。

  • request:每次HTTP請求都會建立一個新的Bean。該做用域僅適用於WebApplicationContext環境。

  • session:一個HTTP Session定義一個Bean。該做用域僅適用於WebApplicationContext環境。

  • globalSession:同一個全局HTTP Session定義一個Bean。該做用域一樣僅適用於WebApplicationContext環境。

bean默認的scope屬性是"singleton"。

十一、Spring 的單例實現原理

Spring框架對單例的支持是採用單例註冊表的方式進行實現的,而這個註冊表的緩存是HashMap對象,若是配置文件中的配置信息不要求使用單例,Spring會採用新建實例的方式返回對象實例。

十二、解釋Spring框架中bean的生命週期

ApplicationContext容器中,Bean的生命週期流程如上圖所示,流程大體以下:


v2-e87d88dc80c2ee64c699d017084b6e4c_hd.jpg


1.首先容器啓動後,會對scope爲singleton且非懶加載的bean進行實例化,

2.按照Bean定義信息配置信息,注入全部的屬性,

3.若是Bean實現了BeanNameAware接口,會回調該接口的setBeanName()方法,傳入該Bean的id,此時該Bean就得到了本身在配置文件中的id,

4.若是Bean實現了BeanFactoryAware接口,會回調該接口的setBeanFactory()方法,傳入該Bean的BeanFactory,這樣該Bean就得到了本身所在的BeanFactory,

5.若是Bean實現了ApplicationContextAware接口,會回調該接口的setApplicationContext()方法,傳入該Bean的ApplicationContext,這樣該Bean就得到了本身所在的ApplicationContext,

6.若是有Bean實現了BeanPostProcessor接口,則會回調該接口的postProcessBeforeInitialzation()方法,

7.若是Bean實現了InitializingBean接口,則會回調該接口的afterPropertiesSet()方法,

8.若是Bean配置了init-method方法,則會執行init-method配置的方法,

9.若是有Bean實現了BeanPostProcessor接口,則會回調該接口的postProcessAfterInitialization()方法,

10.通過流程9以後,就能夠正式使用該Bean了,對於scope爲singleton的Bean,Spring的ioc容器中會緩存一份該bean的實例,而對於scope爲prototype的Bean,每次被調用都會new一個新的對象,期生命週期就交給調用方管理了,再也不是Spring容器進行管理了

11.容器關閉後,若是Bean實現了DisposableBean接口,則會回調該接口的destroy()方法,

12.若是Bean配置了destroy-method方法,則會執行destroy-method配置的方法,至此,整個Bean的生命週期結束

1三、Resource 是如何被查找、加載的?

Resource 接口是 Spring 資源訪問策略的抽象,它自己並不提供任何資源訪問實現,具體的資源訪問由該接口的實現類完成——每一個實現類表明一種資源訪問策略。 Spring 爲 Resource 接口提供了以下實現類:

  • UrlResource:訪問網絡資源的實現類。

  • ClassPathResource:訪問類加載路徑裏資源的實現類。

  • FileSystemResource:訪問文件系統裏資源的實現類。

  • ServletContextResource:訪問相對於 ServletContext 路徑裏的資源的實現類:

  • InputStreamResource:訪問輸入流資源的實現類。

  • ByteArrayResource:訪問字節數組資源的實現類。 這些 Resource 實現類,針對不一樣的的底層資源,提供了相應的資源訪問邏輯,並提供便捷的包裝,以利於客戶端程序的資源訪問。

1四、解釋自動裝配的各類模式?

自動裝配提供五種不一樣的模式供Spring容器用來自動裝配beans之間的依賴注入:

no:默認的方式是不進行自動裝配,經過手工設置ref 屬性來進行裝配bean。

byName:經過參數名自動裝配,Spring容器查找beans的屬性,這些beans在XML配置文件中被設置爲byName。以後容器試圖匹配、裝配和該bean的屬性具備相同名字的bean。

byType:經過參數的數據類型自動自動裝配,Spring容器查找beans的屬性,這些beans在XML配置文件中被設置爲byType。以後容器試圖匹配和裝配和該bean的屬性類型同樣的bean。若是有多個bean符合條件,則拋出錯誤。

constructor:這個同byType相似,不過是應用於構造函數的參數。若是在BeanFactory中不是剛好有一個bean與構造函數參數相同類型,則拋出一個嚴重的錯誤。

autodetect:若是有默認的構造方法,經過 construct的方式自動裝配,不然使用 byType的方式自動裝配。

1五、Spring中的依賴注入是什麼?

依賴注入做爲控制反轉(IOC)的一個層面,能夠有多種解釋方式。在這個概念中,你不用建立對象而只須要描述如何建立它們。你沒必要經過代碼直接的將組件和服務鏈接在一塊兒,而是經過配置文件說明哪些組件須要什麼服務。以後IOC容器負責銜接。

1六、有哪些不一樣類型的IOC(依賴注入)?

構造器依賴注入:構造器依賴注入在容器觸發構造器的時候完成,該構造器有一系列的參數,每一個參數表明注入的對象。

Setter方法依賴注入:首先容器會觸發一個無參構造函數或無參靜態工廠方法實例化對象,以後容器調用bean中的setter方法完成Setter方法依賴注入。

1七、你推薦哪一種依賴注入?構造器依賴注入仍是Setter方法依賴注入?

你能夠同時使用兩種方式的依賴注入,最好的選擇是使用構造器參數實現強制依賴注入,使用setter方法實現可選的依賴關係。

1八、Spring IOC 如何實現

Spring中的 org.springframework.beans 包和 org.springframework.context包構成了Spring框架IoC容器的基礎。

BeanFactory 接口提供了一個先進的配置機制,使得任何類型的對象的配置成爲可能。ApplicationContex接口對BeanFactory(是一個子接口)進行了擴展,在BeanFactory的基礎上添加了其餘功能,好比與Spring的AOP更容易集成,也提供了處理message resource的機制(用於國際化)、事件傳播以及應用層的特別配置,好比針對Web應用的WebApplicationContext。

org.springframework.beans.factory.BeanFactory 是Spring IoC容器的具體實現,用來包裝和管理前面提到的各類bean。BeanFactory接口是Spring IoC 容器的核心接口。

1九、Spring IoC容器是什麼?

Spring IOC負責建立對象、管理對象(經過依賴注入)、整合對象、配置對象以及管理這些對象的生命週期。

20、IoC有什麼優勢?

IOC或依賴注入減小了應用程序的代碼量。它使得應用程序的測試很簡單,由於在單元測試中再也不須要單例或JNDI查找機制。簡單的實現以及較少的干擾機制使得鬆耦合得以實現。IOC容器支持勤性單例及延遲加載服務。

2一、解釋AOP模塊

AOP模塊用來開發Spring應用程序中具備切面性質的部分。該模塊的大部分服務由AOP Aliance提供,這就保證了Spring框架和其餘AOP框架之間的互操做性。另外,該模塊將元數據編程引入到了Spring。

2二、Spring面向切面編程(AOP)

面向切面編程(AOP):容許程序員模塊化橫向業務邏輯,或定義核心部分的功能,例如日誌管理和事務管理。

切面(Aspect) :AOP的核心就是切面,它將多個類的通用行爲封裝爲可重用的模塊。該模塊含有一組API提供 cross-cutting功能。例如,日誌模塊稱爲日誌的AOP切面。根據需求的不一樣,一個應用程序能夠有若干切面。在Spring AOP中,切面經過帶有@Aspect註解的類實現。

通知(Advice):通知表示在方法執行先後須要執行的動做。實際上它是Spring AOP框架在程序執行過程當中觸發的一些代碼。Spring切面能夠執行一下五種類型的通知:

  • before(前置通知):在一個方法以前執行的通知。

  • after(最終通知):當某鏈接點退出的時候執行的通知(不管是正常返回仍是異常退出)。

  • after-returning(後置通知):在某鏈接點正常完成後執行的通知。

  • after-throwing(異常通知):在方法拋出異常退出時執行的通知。

  • around(環繞通知):在方法調用先後觸發的通知。

切入點(Pointcut):切入點是一個或一組鏈接點,通知將在這些位置執行。能夠經過表達式或匹配的方式指明切入點。

引入:引入容許咱們在已有的類上添加新的方法或屬性。

目標對象:被一個或者多個切面所通知的對象。它一般是一個代理對象。也被稱作被通知(advised)對象。

代理:代理是將通知應用到目標對象後建立的對象。從客戶端的角度看,代理對象和目標對象是同樣的。有如下幾種代理:

  • BeanNameAutoProxyCreator:bean名稱自動代理建立器

  • DefaultAdvisorAutoProxyCreator:默認通知者自動代理建立器

  • Metadata autoproxying:元數據自動代理

織入:將切面和其餘應用類型或對象鏈接起來建立一個通知對象的過程。織入能夠在編譯、加載或運行時完成。

2三、Spring AOP 實現原理

實現AOP的技術,主要分爲兩大類:

  • 一是採用動態代理技術,利用截取消息的方式,對該消息進行裝飾,以取代原有對象行爲的執行;

  • 二是採用靜態織入的方式,引入特定的語法建立「方面」,從而使得編譯器能夠在編譯期間織入有關「方面」的代碼。

Spring AOP 的實現原理其實很簡單:AOP 框架負責動態地生成 AOP 代理類,這個代理類的方法則由 Advice和回調目標對象的方法所組成, 並將該對象可做爲目標對象使用。AOP 代理包含了目標對象的所有方法,但AOP代理中的方法與目標對象的方法存在差別,AOP方法在特定切入點添加了加強處理,並回調了目標對象的方法。

Spring AOP使用動態代理技術在運行期織入加強代碼。使用兩種代理機制:基於JDK的動態代理(JDK自己只提供接口的代理)和基於CGlib的動態代理。

  • (1) JDK的動態代理
    JDK的動態代理主要涉及java.lang.reflect包中的兩個類:Proxy和InvocationHandler。其中InvocationHandler只是一個接口,能夠經過實現該接口定義橫切邏輯,並經過反射機制調用目標類的代碼,動態的將橫切邏輯與業務邏輯織在一塊兒。而Proxy利用InvocationHandler動態建立一個符合某一接口的實例,生成目標類的代理對象。
    其代理對象必須是某個接口的實現, 它是經過在運行期間建立一個接口的實現類來完成對目標對象的代理.只能實現接口的類生成代理,而不能針對類

  • (2)CGLibCGLib採用底層的字節碼技術,爲一個類建立子類,並在子類中採用方法攔截的技術攔截全部父類的調用方法,並順勢織入橫切邏輯.它運行期間生成的代理對象是目標類的擴展子類.因此沒法通知final、private的方法,由於它們不能被覆寫.是針對類實現代理,主要是爲指定的類生成一個子類,覆蓋其中方法.在spring中默認狀況下使用JDK動態代理實現AOP,若是proxy-target-class設置爲true或者使用了優化策略那麼會使用CGLIB來建立動態代理.Spring AOP在這兩種方式的實現上基本同樣.以JDK代理爲例,會使用JdkDynamicAopProxy來建立代理,在invoke()方法首先須要織入到當前類的加強器封裝到攔截器鏈中,而後遞歸的調用這些攔截器完成功能的織入.最終返回代理對象.

相關文章
相關標籤/搜索