文章目錄
- Spring的IOC和AOP機制
- IOC(DI)
- AOP
- Spring AOP 和 AspectJ AOP 有什么區別?
- Spring中Bean的作用域有哪些
- Spring中單例Bean的執行緒安全問題了解嗎
- @Component 和 @Bean 的區別是什么?
- Spring中Bean的生命周期
- SpringMVC的執行流程
- Spring框架中用到了哪些設計模式
- @Transactional(rollbackFor = Exception.class)注解了解嗎?
- BeanFactory和ApplicationContext有什么區別?
- 什么是Bean裝配
- Spring自動裝配Bean有哪些方式
- Spring實作事務的原理
- Spring 管理事務的方式有幾種?
- Spring 事務中的隔離級別有哪幾種?
- Spring的回圈依賴
- Spring事務什么時候會失效
- SpringMVC的作業流程
- SpringBoot自動裝配原理
- 如何理解 Spring Boot 中的 Starter
Spring的IOC和AOP機制
我們在使用Spring框架的程序中,其實就是為了使用IOC,依賴注入和AOP,面向切面編程,這兩個是Spring的靈魂
主要用到的設計模式有工廠設計模式和代理設計模式
(1)IOC就是典型的工廠模式,通過sessionfactory注入實體
(2)AOP就是典型的代理模式的體現
代理模式是常用的java設計模式,他的特征是代理類與委托類有同樣的介面,代理類主要負責為委托類預處理訊息,過濾訊息,把訊息轉發給委托類以及事后處理訊息等,代理類與委托類之間通常會存在關聯關系,一個代理類物件與一個委托類的物件關聯,代理類的物件本身并不是真正實作服務,而是通過呼叫委托類的相關方法,來提供特定的服務
spring的IOC容器是spring的核心,spring AOP是spring框架的重要組成部分
IOC(DI)
在傳統的程式設計中,當呼叫者需要被呼叫者的協助時,通常由呼叫者來1創建被呼叫者的實體,但在spring里創建被呼叫者到的作業不再由呼叫者來完成,因此被稱為控制反轉(IOC)
IOC(Inverse of Control:控制反轉)是一種設計思想,就是 將原本在程式中手動創建物件的控制權,交由Spring框架來管理, IOC在其他語言中也有應用,并非 Spring 特有, IOC容器是 Spring 用來實作 IOC的載體, IoC 容器實際上就是個Map(key,value),Map 中存放的是各種物件,
IOC容器就像是一個工廠一樣,當我們需要創建一個物件的時候,只需要配置好組態檔/注解即可,完全不用考慮物件是如何被創建出來的,
IOC利用了工廠模式,將物件交給容器管理,你只需要再spring組態檔中配置相應的bean,以及設定相關的屬性,讓spring容器來生成類的實體物件以及管理物件,在spring容器啟動的時候,spring會把你在組態檔中配置的bean都初始化好,然后在你需要呼叫的時候,就把它以及初始化好的那些bean分配給你需要呼叫的那些bean的類(假設這個類名為A),分配的方式是呼叫A的setter方法來注入,而不需要你再A里面new這些bean了
? 
AOP
AOP(Aspect-Oriented Programming:面向切面編程)能夠將那些與業務無關,卻為業務模塊所共同呼叫的邏輯或責任(例如事務處理、日志管理、權限控制等)封裝起來,便于減少系統的重復代碼,降低模塊間的耦合度,并有利于未來的可拓展性和可維護性,
? 實作AOP的技術,主要分為兩大類:
? (1)采用動態代理技術,利用截取訊息的方法,對該物件進行裝飾,以取代原有物件行為的執行,
? (2)采用靜態織入的方式,引入特定的語法創建"方面",從而使得編譯器在編譯期間織入有關"方面"的代碼,
? AOP實作的關鍵在于代理模式,AOP的代理主要分為靜態代理和動態代理,靜態代理的代表為AspectJ,動態代理的代表則以SpringAOP為代表
? (1)AspectJ是靜態代理的增加,所謂靜態代理,就是AOP框架會在編譯階段生成AOP代理類,因此也稱為編譯時增強,她會在編譯階段將AspectJ(切面)織入到Java位元組碼中,運行的時候就是增強之后的AOP物件,
? (2)Spring AOP使用的是動態代理,所謂的動態代理就是說AOP框架不會去修改位元組碼,而是每次運行時在記憶體中臨時為方法生成一個AOP物件,這個AOP物件包含了目標物件的全部方法,并且在特定的切點做了增強處理,并回呼原物件的方法
AOP中的動態代理主要有兩種方式,JDK動態代理和CGLIB的動態代理
Spring AOP 和 AspectJ AOP 有什么區別?
- Spring AOP 屬于運行時增強,而 AspectJ 是編譯時增強, Spring AOP 基于代理(Proxying),而 AspectJ 基于位元組碼操作(Bytecode Manipulation),
- AspectJ 相比于 Spring AOP 功能更加強大,但是 Spring AOP 相對來說更簡單,
- 如果我們的切面比較少,那么兩者性能差異不大,但是,當切面太多的話,最好選擇 AspectJ ,它比Spring AOP 快很多,
Spring中Bean的作用域有哪些
- singleton : 唯一 bean 實體,Spring 中的 bean 默認都是單例的,
- prototype : 每次請求都會創建一個新的 bean 實體,
- request : 每一次HTTP請求都會產生一個新的bean,該bean僅在當前HTTP request內有效,
- session : 每一次HTTP請求都會產生一個新的 bean,該bean僅在當前 HTTP session 內有效,
- application:bean被定義為在ServletContext的生命周期中復用的一個單例物件,
- websocket:bean被定義為在websocket的生命周期中復用的一個單例物件,
- blobal-session:全域作用域,
Spring中單例Bean的執行緒安全問題了解嗎
的確是存在安全問題的,因為,當多個執行緒操作同一個物件的時候,對這個物件的成員變數的寫操作會存在執行緒安全問題,即如果Bean時有狀態的(有狀態的意思就是說有資料存盤功能),那么需要開發人員來保證執行緒安全,
一般情況下,我們常用的 Controller、Service、Dao 這些 Bean 是無狀態的,無狀態的 Bean 不能保存資料,因此是執行緒安全的,
常用的解決辦法有兩種:
- 在類中定義一個 ThreadLocal 成員變數,將需要的可變成員變數保存在 ThreadLocal 中(推薦的一種方式),
- 改變 Bean 的作用域為
prototype:每次請求都會創建一個新的 bean 實體,自然不會存在執行緒安全問題,
@Component 和 @Bean 的區別是什么?
- 作用物件不同:
@Component注解作用于類,而@Bean注解作用于方法, @Component通常是通過類路徑掃描來自動偵測以及自動裝配到Spring容器中(我們可以使用@Component注解定義掃描的路徑從中找出標識了需要裝配的類自動裝配到Spring的Bean容器中),@Bean注解通常是我們在標有該注解的方法中定義產生這個Bean,@Bean告訴了Spring這是某個類的示例,當我需要用的時候把他給我,@Bean注解比@Component注解的自定義性更強,而且很多地方我們只能通過@Bean注解來注冊Bean,比如當我們參考第三方庫中的類需要裝配到 Spring 容器時,則只能通過@Bean來實作,
Spring中Bean的生命周期
- Bean 容器找到組態檔中 Spring Bean 的定義,
- 如果有多個構造方法,則要推斷需要執行哪一個構造方法,
- 確定好構造方法后,進行實體化得到一個物件,
- 對加入了@Autowired注解的物件的屬性進行填充,
- 回呼Aware方法對Bean容器進行一系列的初始化操作,比如BeanNameAware、BeanFactoryAware,
- 呼叫BeanPostProcessor的初始化的前方法,
- 呼叫初始化方法,
- 呼叫BeanPostProcessor的初始化的后方法,在這里會進行AOP,
- 如果當前創建的Bean是單例的,那么會把Bean放入單例池,
- 程式員使用Bean,
- Spring容器關閉時呼叫DisposableBean中的destory()方法,

SpringMVC的執行流程
-
用戶發送請求至前端控制器
DispatcherServlet, -
DispatcherServlet收到請求呼叫HandlerMapping處理器映射器, -
處理器映射器找到具體的處理器(可以根據xml配置、注解進行查找),生成處理器物件及處理器攔截器(如果有則生成)一并回傳給
DispatcherServlet, -
DispatcherServlet呼叫HandlerAdapter處理器配接器, -
HandlerAdapter經過適配呼叫具體的處理器(Controller,也叫后端控制器), -
Controller執行完成回傳ModelAndView, -
HandlerAdapter將Controller執行結果ModelAndView回傳給DispatcherServlet, -
DispatcherServlet將ModelAndView傳給ViewReslover視圖決議器, -
ViewReslover決議后回傳具體View, -
DispatcherServlet根據View進行渲染視圖(即將模型資料填充至視圖中), -
DispatcherServlet回應用戶,
Spring框架中用到了哪些設計模式
- 工廠設計模式 : Spring使用工廠模式通過
BeanFactory、ApplicationContext創建 bean 物件, - 代理設計模式 :Spring AOP 功能的實作,
- 單例設計模式 :Spring 中的 Bean 默認都是單例的,
- 模板方法模式 : Spring 中
jdbcTemplate、hibernateTemplate等以 Template 結尾的對資料庫操作的類,它們就使用到了模板模式, - 包裝器設計模式 :我們的專案需要連接多個資料庫,而且不同的客戶在每次訪問中根據需要會去訪問不同的資料庫,這種模式讓我們可以根據客戶的需求能夠動態切換不同的資料源,
- 觀察者模式:Spring 事件驅動模型就是觀察者模式很經典的一個應用,Spring中Observer(觀察者模式)最常用的地方就是Listener監聽器,
- 配接器模式 :Spring定義了一個配接器介面,使得每一種Controller都有一種對應的配接器實作類,讓配接器代替Controller執行相應的方法,這樣在拓展Controller時,只需增加一個配接器類就完成了SpringMVC的拓展了,
- 裝飾器模式:動態地給一個物件添加一些額外的職責,Spring中用到的包裝器模式在類名上有兩種表現:一種時類名中含有Wrapper,另一種時類名中含有Decorator,
- 策略模式:Spring框架的資源訪問Resource介面,該介面提供了更強的資源訪問能力,Spring框架本身大量使用了Resource介面來訪問底層資源,
@Transactional(rollbackFor = Exception.class)注解了解嗎?
Exception分為運行時例外RuntimeException和非運行時例外,事務管理對于企業應用來說是至關重要的,即使出現例外情況,它也可以保證資料的一致性,
當@Transactional注解作用于類上時,該類的所有 public 方法將都具有該型別的事務屬性,同時,我們也可以在方法級別使用該標注來覆寫類級別的定義,如果類或者方法加了這個注解,那么這個類里面的方法拋出例外,就會回滾,資料庫里面的資料也會回滾,
在@Transactional注解中如果不配置rollbackFor屬性,那么事務只會在遇到RuntimeException的時候才會回滾,加上rollbackFor=Exception.class,可以讓事務在遇到非運行時例外時也回滾,
BeanFactory和ApplicationContext有什么區別?
BeanFactory和ApplicationContext是Spring的兩大核心介面,都可以當做Spring的容器,其中ApplicationContext是BeanFactory的子介面,
- BeanFactory是Spring中最底層的介面,包含了各種Bean的定義、讀取組態檔、管理Bean的加載、Bean的實體化、控制Bean的生命周期,維護Bean之間的依賴,ApplicationContext介面作為BeanFactory的派生,除了具有BeanFactory所具有的功能外,他還具有其他功能:支持國際化、統一資源檔案的訪問方式、同時加載多個組態檔,
- BeanFactory時采用延遲加載的形式來注入Bean的,即只有在某個Bean時(呼叫getBean()),才對該Bean進行加載實體化, 這樣我們就不能發現一些spring存在的配置問題,如果Bean的某一個屬性沒有注入,BeanFactory加載后直到第一次呼叫getBean方法才會拋出例外,
- ApplicationContext它是在容器啟動的時候,一次性創建了所有的Bean,這樣在容器啟動的時候,我們就可以發現Spring中存在的配置錯誤,這樣有利于檢查依賴屬性是否注入,ApplicationContext啟動后會預載入所有的單實體Bean,通過預載入單實體的Bean,確保你在需要的時候,可以不需要等待,直接取用,
- 相對于BeanFactory,ApplicationContext唯一的不足時占用記憶體,當應用程式配置的Bean較多的時候,程式啟動會比較慢,
- BeanFacotry通常是以編程的方式被創建的,而ApplicationContext還可以以宣告的方式來創建,比如說ContextLoader,
- BeanFactory和ApplicationContex都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但是兩者之間的區別是:BeanFactory需要手動注冊,而ApplicationContext則是自動注冊,
什么是Bean裝配
裝配是指在Spring容器中把bean組裝在一起,
在Spring框架中,在組態檔設定bean依賴關系是一個很好的機制,Spring容器可以自動裝配互相合作的bean,這樣意味著容器不需要配置就能夠通過Bean工廠發自動處理Bean之間的協作,
Spring自動裝配Bean有哪些方式
在Spring的組態檔中共有五種自動裝配:
- no:默認的方式是不通過自動裝配,通過手動ref屬性來進行裝配Bean,
- byName:通過Bean的名稱進行自動裝配,如果一個Bean的property與另一個Bean的name相同,就會進行自動裝配,
- byType:通過引數的資料型別進行自動裝配,
- constructor:通過建構式進行自動裝配,并且建構式的引數也是通過byType進行裝配的,
- autodetect:自動探測,如果有構造方法就是使用construct的方式自動裝配,否則使用byType的方式自動裝配,
Spring實作事務的原理
在使用Spring框架時,可以有兩種使用事務的方式,一種是編程式事務,另一種是宣告式事務,@Transaction注解就是宣告式事務,
首先事務的概念是在資料庫層面的,Spring只是基于資料庫中的事務進行了拓展,以及提供了一些能讓程式員更既方便操作事務的方式,比如我們可以在某個方法上增加@Transaction注解,開啟事務,這個方法中的所有sql都會在一個事務中執行,統一成功或者統一失敗,
在一個方法上加了@Transaction注解后,Spring會基于這個類生成一個代理物件,會將這個這個代理物件作為bean,在當使用這個代理物件的方法時,如果中國方法上存在@Transaction注解,那么代理邏輯會把事務的自動提交設定為false,然后再去執行原本的業務邏輯方法,如果執行的業務邏輯沒有出現例外,那么代理邏輯中就會將事務進行提交,如果執行的業務邏輯方法出現了例外,那么會將事務進行回滾,
針對哪些例外回滾事務是可以配置的,可以利用@Transaction注解中的rollbackFor屬性進行配置,默認會對RuntimeException和Error進行回滾,
Spring 管理事務的方式有幾種?
- 編程式事務:在代碼中硬編碼,(不推薦使用)
- 宣告式事務:在組態檔中配置,(推薦)
- 基于XML的宣告式事務
- 基于注解的宣告式事務
Spring 事務中的隔離級別有哪幾種?
TransactionDefinition 介面中定義了五個表示隔離級別的常量:
- TransactionDefinition.ISOLATION_DEFAULT:使用后端資料庫默認的隔離級別,MySQL采用REPEATABLE_READ隔離級別 Oracle 默認采用的 READ_COMMITTED隔離級別,
- TransactionDefinition.ISOLATION_READ_UNCOMMITTED:最低的隔離級別,允許讀取未提交的資料,可能會導致臟讀、幻讀、不可重復讀,
- TransactionDefinition.ISOLATION_READ_COMMITTED:允許去讀并發事務已提交的資料,可以阻止臟讀,但是幻讀或者不可重復讀可能發生,
- TransactionDefinition.ISOLATION_REPEATABLE_READ:對同一個欄位多次讀取結果都是一致的,除非資料時被本身事務自己所修改,可以阻止臟讀和不可重復讀,但是幻讀仍然可能發生,
- TransactionDefinition.ISOLATION_SERIALIZABLE:最高的隔離級別1,完全服從ACID的隔離級別,所有事務依次逐個執行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止臟讀、不可重復讀以及幻讀,
Spring的回圈依賴
- A創建程序中需要B,于是A將自己放到三級快取中,去實體化B,
- B實體化的時候發現需要A,于是B先去查一級快取,發現找不到,然后去查二級快取,還是沒有,接著再去找三級快取,找到了A,于是把三級快取里面的這個A放到二級快取中,并洗掉三級快取里面的A,
- B順利初始化完畢,將自己放到一級快取里面(此時B里面的A依然是創建中的狀態),然后接著回來創建A,此時B已經創建結束,直接從一級快取中拿到B,然后完成創建,并將A自己放到一級快取里面,
Spring事務什么時候會失效
- 發生自呼叫,
- 方法不是public的,@Transaction只能用于public方法,否則事務會失效,如果要用到非public方法上,可以開啟AspectJ代理模式,
- 資料庫不支持事務的,
- 沒有被Spring管理的,
- 例外被catch了,事務不會回滾,
SpringMVC的作業流程
- 客戶端(瀏覽器)發送請求,直接請求到 DispatcherServlet,
- DispatcherServlet 根據請求資訊呼叫 HandlerMapping,決議請求對應的 Handler,
- 決議到對應的 Handler(也就是我們平常說的 Controller 控制器)后,開始由 HandlerAdapter 配接器處理,
- HandlerAdapter 會根據 Handler來呼叫真正的處理器開始處理請求,并處理相應的業務邏輯,
- Handler處理器處理完業務后,會回傳一個 ModelAndView 物件,Model 是回傳的資料物件,View 是個邏輯上的 View,
- HandlerAdapter將Handler執行結果ModelAndView回傳到DispatcherServlet,
- DispatcherServlet將ModelAndView傳給ViewReslover視圖決議器,
- ViewReslover決議后回傳具體View,
- DispatcherServlet對View進行渲染視圖(即將模型資料model填充至視圖中),
- DispatcherServlet回應用戶,
SpringBoot自動裝配原理

如何理解 Spring Boot 中的 Starter
比如傳統使用spring+springmvc,如果需要引入mybatis等框架,需要到xml中定義mybatis需要的bean,
stater就是定義一個start的jar包,寫一個@Configuration配置類,將這些bean定義在里賣弄,然后在start包的META-INF/spring.factories中寫入該配置類,springboot會按照約定來加載該配置類,
開發人員只需要將相應的start包依賴引入到應用,然后進行相應的屬性配置,也有默認的配置,就可以直接進行代碼的開發了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/290644.html
標籤:java
