spring學習筆記(1)

了飄塵發表於2020-12-02

1、什麼是Spring?

Spring是一個開源的Java EE開發框架。Spring框架的核心功能可以應用在任何Java應用程式中,但對Java EE平臺上的Web應用程式有更好的擴充套件性。Spring框架的目標是使得Java EE應用程式的開發更加簡捷,通過使用POJO為基礎的程式設計模型促進良好的程式設計風格。

2、Spring有哪些優點?

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

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

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

容器:Spring包含並管理應用程式物件的配置及生命週期。

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

事務管理:Spring對下至本地業務上至全域性業務(JAT)提供了統一的事務管理介面。

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

3、Spring 事務實現方式

  • 程式設計式事務管理:這意味著你可以通過程式設計的方式管理事務,這種方式帶來了很大的靈活性,但很難維護。
  • 宣告式事務管理:這種方式意味著你可以將事務管理和業務程式碼分離。你只需要通過註解或者XML配置管理事務。

4、Spring框架的事務管理有哪些優點

  • 它為不同的事務API(如JTA, JDBC, Hibernate, JPA, 和JDO)提供了統一的程式設計模型。
  • 它為程式設計式事務管理提供了一個簡單的API而非一系列複雜的事務API(如JTA).
  • 它支援宣告式事務管理。
  • 它可以和Spring 的多種資料訪問技術很好的融合。

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

  • PROPAGATION_REQUIRED: 支援當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。
  • PROPAGATION_SUPPORTS: 支援當前事務,如果當前沒有事務,就以非事務方式執行。
  • PROPAGATION_MANDATORY: 支援當前事務,如果當前沒有事務,就丟擲異常。
  • PROPAGATION_REQUIRES_NEW: 新建事務,如果當前存在事務,把當前事務掛起。
  • PROPAGATION_NOT_SUPPORTED: 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
  • PROPAGATION_NEVER: 以非事務方式執行,如果當前存在事務,則丟擲異常。
  • PROPAGATION_NESTED: 如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。

6、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宣告式事務處理的設計體系。

7、Spring MVC 執行流程

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

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

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

第四步:前端控制器呼叫處理器介面卡去執行Handler

第五步:處理器介面卡去執行Handler

第六步:Handler執行完成給介面卡返回ModelAndView

第七步:處理器介面卡向前端控制器返回ModelAndView(ModelAndView是springmvc框架的一個底層物件,包括Model和view)

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

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

第十步:前端控制器進行檢視渲染( 檢視渲染將模型資料(在ModelAndView物件中)填充到request域)

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

8、BeanFactory和ApplicationContext有什麼區別?

ApplicationContext提供了一種解決文件資訊的方法,一種載入檔案資源的方式(如圖片),他們可以向監聽他們的beans傳送訊息。另外,容器或者容器中beans的操作,這些必須以bean工廠的程式設計方式處理的操作可以在應用上下文中以宣告的方式處理。應用上下文實現了MessageSource,該介面用於獲取本地訊息,實際的實現是可選的。

相同點:兩者都是通過xml配置檔案載入bean,ApplicationContext和BeanFacotry相比,提供了更多的擴充套件功能。

不同點:BeanFactory是延遲載入,如果Bean的某一個屬性沒有注入,BeanFacotry載入後,直至第一次使用呼叫getBean方法才會丟擲異常;而ApplicationContext則在初始化自身是檢驗,這樣有利於檢查所依賴屬性是否注入;所以通常情況下我們選擇使用ApplicationContext。

9、什麼是Spring Beans?

Spring Beans是構成Spring應用核心的Java物件。這些物件由Spring IOC容器例項化、組裝、管理。這些物件通過容器中配置的後設資料建立,例如,使用XML檔案中定義的建立。

在Spring中建立的beans都是單例的beans。在bean標籤中有一個屬性為”singleton”,如果設為true,該bean是單例的,如果設為false,該bean是原型bean。Singleton屬性預設設定為true。因此,spring框架中所有的bean都預設為單例bean。

10、說一下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"。

11、Spring 的單例實現原理

Spring框架對單例的支援是採用單例登錄檔的方式進行實現的,而這個登錄檔的快取是HashMap物件,如果配置檔案中的配置資訊不要求使用單例,Spring會採用新建例項的方式返回物件例項。

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

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

img

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的生命週期結束

13、Resource 是如何被查詢、載入的?

Resource 介面是 Spring 資源訪問策略的抽象,它本身並不提供任何資源訪問實現,具體的資源訪問由該介面的實現類完成——每個實現類代表一種資源訪問策略。 Spring 為 Resource 介面提供瞭如下實現類:

  • UrlResource:訪問網路資源的實現類。
  • ClassPathResource:訪問類載入路徑裡資源的實現類。
  • FileSystemResource:訪問檔案系統裡資源的實現類。
  • ServletContextResource:訪問相對於 ServletContext 路徑裡的資源的實現類:
  • InputStreamResource:訪問輸入流資源的實現類。
  • ByteArrayResource:訪問位元組陣列資源的實現類。 這些 Resource 實現類,針對不同的的底層資源,提供了相應的資源訪問邏輯,並提供便捷的包裝,以利於客戶端程式的資源訪問。

14、解釋自動裝配的各種模式?

自動裝配提供五種不同的模式供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的方式自動裝配。

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

依賴注入作為控制反轉(IOC)的一個層面,可以有多種解釋方式。在這個概念中,你不用建立物件而只需要描述如何建立它們。你不必通過程式碼直接的將元件和服務連線在一起,而是通過配置檔案說明哪些元件需要什麼服務。之後IOC容器負責銜接。

16、有哪些不同型別的IOC(依賴注入)?

構造器依賴注入:構造器依賴注入在容器觸發構造器的時候完成,該構造器有一系列的引數,每個引數代表注入的物件。

Setter方法依賴注入:首先容器會觸發一個無參建構函式或無參靜態工廠方法例項化物件,之後容器呼叫bean中的setter方法完成Setter方法依賴注入。

17、你推薦哪種依賴注入?構造器依賴注入還是Setter方法依賴注入?

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

18、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 容器的核心介面。

19、Spring IoC容器是什麼?

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

20、IoC有什麼優點?

IOC或依賴注入減少了應用程式的程式碼量。它使得應用程式的測試很簡單,因為在單元測試中不再需要單例或JNDI查詢機制。簡單的實現以及較少的干擾機制使得鬆耦合得以實現。IOC容器支援勤性單例及延遲載入服務。

21、解釋AOP模組

AOP模組用來開發Spring應用程式中具有切面性質的部分。該模組的大部分服務由AOP Aliance提供,這就保證了Spring框架和其他AOP框架之間的互操作性。另外,該模組將後設資料程式設計引入到了Spring。

22、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:後設資料自動代理

織入:將切面和其他應用型別或物件連線起來建立一個通知物件的過程。織入可以在編譯、載入或執行時完成。

23、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)CGLib
        CGLib採用底層的位元組碼技術,為一個類建立子類,並在子類中採用方法攔截的技術攔截所有父類的呼叫方法,並順勢織入橫切邏輯.它執行期間生成的代理物件是目標類的擴充套件子類.所以無法通知final、private的方法,因為它們不能被覆寫.是針對類實現代理,主要是為指定的類生成一個子類,覆蓋其中方法.
        在spring中預設情況下使用JDK動態代理實現AOP,如果proxy-target-class設定為true或者使用了優化策略那麼會使用CGLIB來建立動態代理.Spring AOP在這兩種方式的實現上基本一樣.以JDK代理為例,會使用JdkDynamicAopProxy來建立代理,在invoke()方法首先需要織入到當前類的增強器封裝到攔截器鏈中,然後遞迴的呼叫這些攔截器完成功能的織入.最終返回代理物件.

相關文章