Spring Boot中常用注解及其底層實現
1、@SpringBootApplication注解:
@SpringBootApplication注解:這個注解標識了一個SpringBoot工程,它實際上是另外三個注解的組合,這三個注解是:
- a@SpringBootConfiguration:這個注解實際就是一個@Configuration,表示啟動類也是一個配置類
- b@EnableAutoConfiguration:向Spring容器中導入了一個Selector,用來加載ClassPath下SpringFactories中所定義的自動配置類,將這些自動加載為配置Bean
- c@ComponentScan:自動掃描當前包及其子包中的組件,進行類的注冊。
底層實現:
@EnableAutoConfiguration內部會通過@Import(AutoConfigurationImportSelector.class) 來實現自動配置,Spring Boot 會根據項目中依賴的庫來判斷是否啟用某個自動配置。
2. @Autowired
作用:該注解用于自動注入 Spring 容器中的 bean。Spring 會根據類型自動將依賴的 bean 注入到目標對象中。
底層實現:
@Autowired 通過 Spring 的反射機制實現依賴注入,它會掃描標注了該注解的字段、構造器或 setter 方法,然后將對應的 bean 注入。
3. @RestController
作用:該注解是一個組合注解,等同于 @Controller 和 @ResponseBody,用于定義 RESTful 風格的控制器,方法返回的數據會直接寫入 HTTP 響應體中。
底層實現:
@RestController 本質上是 @Controller 和 @ResponseBody 的組合,@ResponseBody 表示方法的返回值會通過 HTTP 響應直接返回。
4. @RequestMapping / @GetMapping / @PostMapping 等
作用:用于處理 HTTP 請求的映射,指定方法與 HTTP 請求的路徑和類型之間的關系。
- @RequestMapping 是通用的,支持所有 HTTP 方法(如 GET、POST、PUT 等)。
- @GetMapping、@PostMapping 等是 @RequestMapping 的派生注解,分別用于 GET 請求和 POST 請求。
底層實現:
這些注解的底層實現依賴于 Spring MVC 的 HandlerMapping,當請求到達時,Spring 會根據 URL 和請求方法(GET、POST 等)匹配相應的處理方法。
5.@Component / @Service / @Repository / @Controller
作用:這些注解用于將類標記為 Spring 容器管理的組件。
- @Component 是最基本的注解,表示該類是一個 Spring 管理的 bean。
- @Service 是 @Component 的衍生注解,表示該類是一個服務層組件。
- @Repository 是 @Component 的衍生注解,表示該類是數據訪問層的組件,Spring 會提供特定的異常轉換功能。
- @Controller 是用于 Web 層控制器的注解。
底層實現:
這些注解都會被 Spring 的組件掃描器 (@ComponentScan) 掃描并注冊為 Spring 管理的 bean。
6. @Value
作用:用于注入屬性值,可以注入配置文件中的值,也可以注入其他資源中的值。
底層實現:
該注解會通過 Spring 的 Environment 對象來加載外部配置的值,如 application.properties 或 application.yml 中的內容。Spring 會通過反射將這些值注入到標注了 @Value 的字段中。
7. @ConfigurationProperties
作用:用于將配置文件中的屬性值注入到一個 POJO 中,通常用于讀取復雜的配置結構。
底層實現:
@ConfigurationProperties 通過 Spring Boot 的 @EnableConfigurationProperties 注解來啟用支持,并通過 Spring 的 Environment 將配置文件中的值注入到 POJO 的字段中。
8.@EnableAutoConfiguration
作用:啟用 Spring Boot 的自動配置機制,Spring Boot 會根據項目的類路徑自動配置合適的 Bean。
底層實現:
@EnableAutoConfiguration 通過 AutoConfigurationImportSelector 來加載自動配置類。這些自動配置類是 Spring Boot 提供的一些默認配置,基于 META-INF/spring.factories 中定義的配置進行加載。
9.@Bean
作用:定義一個 Bean,并將其注冊到 Spring 容器中,通常用在 @Configuration 注解的類中。
底層實現:
@Bean 會通過 @Configuration 標記的類(實際上是一個代理類)來進行 Spring 容器的注冊。
10. @Profile
作用:用于定義 Bean 在特定環境下的加載條件,可以根據不同的 profile(如
dev
、prod
)來加載不同的配置。底層實現:
@Profile 是通過 Spring 環境的 @Conditional 注解機制實現的,Spring 會根據當前的運行環境選擇性地加載指定的 Bean。
11. @Transactional
作用:聲明式事務管理,標注在方法上,表示該方法需要開啟事務。Spring 會在方法執行時自動開啟事務,方法執行完成后自動提交,若出現異常則回滾。
底層實現:
@Transactional 通過 AOP(面向切面編程)實現,Spring 會通過代理類在方法執行前后添加事務管理的邏輯。
Spring Boot
談談你對IOC的理解
- IOC(Inversion of Control,控制反轉) 是一種設計原則,它的核心思想是:控制權的轉移,即不再由程序代碼顯式控制對象的創建和依賴關系,而是交給容器或框架來管理。
- 在傳統的編程方式中,開發者通常需要手動創建對象并將它們傳遞到需要使用它們的地方。而在 IOC 模式下,控制權反轉,容器會負責對象的創建、管理以及它們之間的依賴關系,這樣可以將對象的創建和使用解耦,使得程序更加靈活和易于擴展。
IOC 的優勢
解耦:
- IOC 最大的優點是降低了組件之間的耦合度。通過容器進行對象的創建和依賴注入,組件之間無需直接引用或關心對方的實現細節,只關心接口或者抽象。
- 這使得系統更加模塊化、靈活,并且容易進行單元測試。
提高可測試性:
- 通過 IOC 容器,依賴項可以很容易地被替換和模擬。例如,可以通過 Mock 對象來測試某個組件的功能,而不需要關心其實際依賴的實現。
增強可維護性和擴展性:
- 由于對象的創建和依賴關系由容器管理,系統的修改變得更加方便。比如,如果需要替換某個服務或組件,只需修改容器配置或 Bean 定義,而不需要修改所有使用該服務的地方。
生命周期管理:
- 在傳統方式中,開發者需要手動管理對象的生命周期,如對象的初始化和銷毀。而在 IOC 中,容器會自動進行管理,從而減輕了開發者的負擔。
單例Bean和單例模式
- 單例模式是一種設計模式,確保某個類在整個系統中只有一個實例。它適用于各種應用場景,包括需要共享資源的組件。
- 單例 Bean是 Spring 中的一個特性,表示 Spring 容器會管理一個 Bean 并確保其在整個容器中只有一個實例。它是基于 單例模式 實現的,但通過 Spring 容器自動管理 Bean 的生命周期和依賴關系。
單例 Bean 與單例模式的區別
范圍與應用場景:
- 單例模式是一個設計模式,強調的是某個類在整個系統中只能有一個實例,通常由開發者手動控制實例的創建。
- 單例 Bean是 Spring 中的一個概念,指的是容器管理的 Bean 在應用生命周期中只有一個實例。Spring 自動處理實例的生命周期,而開發者不需要手動實現實例控制。
實例的創建方式:
- 單例模式通常由類自身控制實例化過程,例如通過靜態方法來獲取實例。
- 單例 Bean由 Spring 容器控制實例化過程,Spring 會自動創建該 Bean,并在整個容器中保持唯一。
線程安全:
- 單例模式中,如果實例的字段或方法不是線程安全的,可能會導致線程安全問題。開發者需要自己保證實例的線程安全性。
- 單例 Bean通常在 Spring 中是線程安全的,但這取決于實際的 Bean 實現。在多線程環境下,Spring 會確保單例 Bean 的線程安全,但 Bean 本身的實現也需要是線程安全的。
生命周期:
- 單例模式的實例通常會在應用程序的整個生命周期內存在,開發者可以控制何時銷毀該實例。
- 單例 Bean的生命周期由 Spring 容器管理,在容器銷毀時,單例 Bean 會被銷毀。
Spring事務傳播機制
多個事務方法相互調用時,事務如何在這些方法間傳播,方法A是一個事務的方法,方法A執行過程中調用了方法B,那么方法B有無事務以及方法B對事務的要求不同都會對方法A的事務具體執行造成影響,同時方法A的事務對方法B的事務執行也有影響,這種影響具體是什么就由兩個方法所定義的事務傳播類型所決定。
Spring 的事務傳播機制(Transaction Propagation)用于定義在方法調用之間,如何傳播事務的邊界。它決定了事務在方法調用過程中的行為,特別是在多個方法相互調用時,如何處理事務的開始、提交和回滾等操作。
Spring 提供了多種事務傳播行為,可以通過@Transactional 注解的 propagation屬性來指定。默認情況下,
propagation
的值是REQUIRED
,即如果當前存在事務,則加入該事務,如果沒有事務,則創建一個新事務。REQUIRES_NEW:創建一個新事務,如果存在當前事務,則掛起該事務。
Spring事務失效的場景與原因分析
- Spring 事務是通過 AOP(面向切面編程)機制實現的,事務的控制是通過代理類進行的。
- 如果方法調用發生在同一個類的內部,Spring 的 AOP 代理無法攔截該方法,因為 Spring 默認使用的是 JDK 動態代理(接口代理)或 CGLIB 代理(子類代理)。對于類內部的調用,代理對象無法起作用,因此事務無法應用。
1、方法內的自調用:Spring事務是基于AOP的,只要使用代理對象調用某個方法時,Spring事務才能生效,而在一個方法中調用使用this.xxx()調用方法時,this并不是代理對象,所以會導致事務失效。
- a解放辦法1:把調用方法拆分到另外一個Bean中
- b解決辦法2:自己注入自己
- c解決辦法3:AopContext.currentProxy()+@EnableAspectJAutoProxy(exposeProxy = true)
2、方法是private的:Spring事務會基于CGLIB來進行AOP,而CGLIB會基于父子類來失效,子類是代理類,父類是被代理類,如果父類中的某個方法是private的,那么子類就沒有辦法重寫它,也就沒有辦法額外增加Spring事務的邏輯。
3、方法是final的:原因和private是一樣的,也是由于子類不能重寫父類中的final的方法4、異常被吃掉:如果Spring事務沒有捕獲到異常,那么也就不會回滾了,默認情況下Spring會捕獲RuntimeException和Error。
5、數據庫連接池配置問題,事務管理依賴于數據庫連接池,配置不當可能導致事務失效。例如,如果連接池中的連接配置不正確,可能導致事務無法正確提交或回滾。
- 確保數據庫連接池支持事務,并且在連接池的配置中啟用事務管理。
- 對于 Spring Boot 項目,確保
application.properties
中數據庫的配置正確。6、類沒有被Spring管理
Spring中的Bean創建的生命周期有哪些步驟
Spring中一個Bean的創建大概分為以下幾個步驟:
1推斷構造方法
2實例化
3填充屬性,也就是依賴注入
4處理Aware回調
5初始化前,處理@PostConstruct注解
6初始化,處理InitializingBean接口
7初始化后,進行AOP以下是 Spring Bean 生命周期的詳細步驟:
(1)Bean 定義加載? ?Spring 容器加載 Bean 的定義(如 XML 配置、注解或 Java 配置)。 (2)實例化 Bean Spring 容器?? 通過反射調用構造函數或工廠方法創建 Bean 的實例。
(3)設置 Bean 的屬性? ?Spring 容器將配置的屬性值注入到 Bean 中(如通過 Setter 方法或字段注入)。
(4)調用 Aware 接口方法? 如果 Bean 實現了 Aware 接口(如 BeanNameAware、 BeanFactoryAware、ApplicationContextAware),Spring 會調用相應的回調方法。 ????????BeanNameAware:設置 Bean 的名稱。
????????BeanFactoryAware:設置 BeanFactory。
????????ApplicationContextAware:設置 ApplicationContext。
(5)BeanPostProcessor 的前置處理? 如果注冊了 BeanPostProcessor,Spring 會調用 postProcessBeforeInitialization() 方法。
(6)初始化 Bean?
???????? 如果 Bean 實現了 InitializingBean 接口,Spring 會調用 afterPropertiesSet() 方法。 如果配置了自定義的初始化方法(如 init-method 或 @PostConstruct),Spring 會調用該方法。
(7)BeanPostProcessor 的后置處理
????????如果注冊了 BeanPostProcessor,Spring 會調用 postProcessAfterInitialization() 方法。
(8)Bean 已就緒? ?Bean 已經初始化完成,可以被應用程序使用。
(9)銷毀 Bean? 如果 Bean 實現了 DisposableBean 接口,Spring 會調用 destroy() 方法。 如果配置了自定義的銷毀方法(如 destroy-method 或 @PreDestroy),Spring 會調用該方法。
Spring中Bean是線程安全的嗎
Spring本身并沒有針對Bean做線程安全的處理,所以:
如果Bean是無狀態的,那么Bean則是線程安全的
如果Bean是有狀態的,那么Bean則不是線程安全的
無狀態的 Bean:
- 如果 Bean 是無狀態的(即它沒有任何實例變量,或者其實例變量是不可變的),那么它就是線程安全的。這類 Bean 的行為不依賴于實例的狀態,不會受到多個線程并發訪問的影響。常見的無狀態 Bean 可能是一些只依賴于輸入參數、沒有成員變量的工具類等。
有狀態的 Bean:
- 如果 Bean 是有狀態的(即它有實例變量,且這些變量在不同請求或線程中可能會被修改),那么它就可能會遇到線程安全問題。多個線程共享同一個 Bean 實例時,可能會導致多個線程修改同一成員變量,從而出現并發問題。這時,必須確保線程安全,通常可以通過同步機制(如
synchronized
)或者使用線程安全的數據結構來避免問題。另外,Bean是不是線程安全,跟Bean的作用域沒有關系,Bean的作用域只是表示Bean的生命周期范圍,對于任何生命周期的Bean都是一個對象,這個對象是不是線程安全的,還是得看這個Bean對象本身。
ApplicationContext和BeanFactory有什么區別
BeanFactory是Spring中非常核心的組件,表示Bean工廠,可以生成Bean,維護Bean,而ApplicationContext繼承了BeanFactory,所以ApplicationContext擁有BeanFactory所有的特點,也是一個Bean工廠,但是ApplicationContext除開繼承了BeanFactory之外,還繼承了諸如EnvironmentCapable、MessageSource、ApplicationEventPublisher等接口,從而ApplicationContext還有獲取系統環境變量、國際化、事件發布等功能,這是BeanFactory所不具備的
Spring中的事務是如何實現的
- Spring事務底層是基于數據庫事務和AOP機制的
- 首先對于使用了@Transactional注解的Bean,Spring會創建一個代理對象作為Bean
- 當調用代理對象的方法時,會先判斷該方法上是否加了@Transactional注解
- 如果加了,那么則利用事務管理器創建一個數據庫連接
- 并且修改數據庫連接的autocommit屬性為false,禁止此連接的自動提交,這是實現Spring事務非常重要的一步
- 然后執行當前方法,方法中會執行sql
- 執行完當前方法后,如果沒有出現異常就直接提交事務
- 如果出現了異常,并且這個異常是需要回滾的就會回滾事務,否則仍然提交事務
- Spring事務的隔離級別對應的就是數據庫的隔離級別
- Spring事務的傳播機制是Spring事務自己實現的,也是Spring事務中最復雜的
- Spring事務的傳播機制是基于數據庫連接來做的,一個數據庫連接一個事務,如果傳播機制配置為需要新開一個事務,那么實際上就是先建立一個數據庫連接,在此新數據庫連接上執行sql
Spring中什么時候@Transactional會失效
- 因為Spring事務是基于代理來實現的,所以某個加了@Transactional的方法只有是被代理對象調用時,那么這個注解才會生效,所以如果是被代理對象來調用這個方法,那么@Transactional是不會失效的。
- 同時如果某個方法是private的,那么@Transactional也會失效,因為底層cglib是基于父子類來實現的,子類是不能重載父類的private方法的,所以無法很好的利用代理,也會導致@Transactianal失效
Spring容器啟動流程是怎樣的
Spring 容器啟動的流程大致可以分為以下幾個步驟:
- 加載配置文件或注解配置。
- 創建
BeanFactory
或ApplicationContext
實例。- 掃描并解析 Bean 定義。
- 創建 Bean 實例并管理其生命周期。
- 進行依賴注入(DI)。
- 初始化 Bean,執行初始化方法。
- 發布應用上下文事件。
- 應用啟動完畢,可以使用容器中的 Bean。
- 容器關閉時,銷毀需要銷毀的 Bean。
1. 加載配置文件(或注解配置)
Spring 容器的啟動一般從配置文件或者注解開始,通常會有以下幾種方式:
- XML 配置文件:通過
ApplicationContext
(如ClassPathXmlApplicationContext
)加載beans.xml
配置文件。- 注解配置:通過
@Configuration
注解的類來進行配置,通常配合@ComponentScan
掃描包中的 Bean。- Java 配置類:使用 Java 配置類(通過
@Configuration
注解的類)來替代 XML 配置。這時,Spring 會根據配置文件或注解掃描指定的包,找到所有的 Bean 定義,解析它們的配置信息(如類名、構造器、屬性等),并生成
BeanDefinition
對象。2. 創建
BeanFactory
(或ApplicationContext
)
ApplicationContext
是 Spring 容器的核心接口,它是BeanFactory
的一個子接口,提供了更多的功能,如國際化、事件傳播等。
BeanFactory
:是 Spring 最基礎的容器,負責管理 Bean 的生命周期和依賴關系。它是ApplicationContext
的父接口。ApplicationContext
:是BeanFactory
的子接口,通常用于更強大的功能,管理 Bean 的創建、初始化、銷毀等過程。在 Spring 容器啟動時,
ApplicationContext
會加載所有的 Bean 定義,并根據它們的配置創建相應的 Bean 實例。3. 掃描和解析 Bean 定義
Spring 會根據配置掃描指定的包,找到所有的 Bean 定義(包括通過
@Component
,@Service
,@Repository
,@Controller
等注解定義的 Bean)。
- 如果是 XML 配置文件,則解析
<bean>
標簽,生成BeanDefinition
。- 如果是注解配置,
@ComponentScan
會掃描包中的類,并根據注解信息創建BeanDefinition
。每個
BeanDefinition
包含了 Bean 的類型、作用域、生命周期等信息。4. 創建 Bean 實例(根據作用域)
Spring 會根據
BeanDefinition
中的信息,創建 Bean 實例。如果是單例(singleton
)作用域,Spring 會在容器啟動時就創建所有的單例 Bean 實例;如果是原型(prototype
)作用域,Spring 會等到真正需要使用 Bean 時再創建實例。
- 單例 Bean:容器啟動時就會創建并緩存一個實例,后續的請求都直接返回該實例。
- 原型 Bean:每次請求都會創建一個新的實例。
5. 依賴注入(DI)
Spring 會根據配置自動注入 Bean 的依賴關系。這是通過反射機制來完成的,Spring 會分析每個 Bean 的構造方法、字段和 setter 方法,根據配置或者注解(如
@Autowired
)來自動注入所需的依賴。
- 構造器注入:Spring 會根據構造器的參數自動注入依賴。
- setter 方法注入:Spring 會使用 setter 方法來注入依賴。
- 字段注入:Spring 會直接注入字段上的依賴(通常結合
@Autowired
注解)。依賴注入會按照 Bean 的定義順序進行,在整個容器啟動過程中,依賴的 Bean 會被注入到目標 Bean 中。
6. 初始化 Bean
在 Bean 的實例化和依賴注入完成后,Spring 會進行 Bean 的初始化過程。初始化的步驟包括:
- 實現
InitializingBean
接口的 Bean:如果 Bean 實現了InitializingBean
接口,則會調用其afterPropertiesSet()
方法。- 自定義初始化方法:如果在 XML 配置中或者注解中定義了初始化方法(
@Bean(initMethod = "initMethod")
),Spring 會在此時調用該方法。對于每個 Bean,Spring 會在初始化過程中執行所需的操作,以確保 Bean 處于可以使用的狀態。
7. 應用上下文事件
在容器初始化的過程中,Spring 會發布一系列的事件。比如,
ContextRefreshedEvent
事件會在容器初始化完成時發布,開發者可以監聽這些事件并做相應的處理。8. Bean 的使用
一旦 Spring 容器啟動并初始化完成,應用就可以通過
ApplicationContext.getBean()
或@Autowired
注解來獲取和使用容器中的 Bean。9. 銷毀 Bean
在容器關閉時,Spring 會銷毀所有需要銷毀的 Bean。Spring 提供了
@PreDestroy
注解和DisposableBean
接口來實現銷毀操作。
@PreDestroy
:注解方法會在容器銷毀時被調用。DisposableBean
:實現該接口的 Bean 會在容器銷毀時調用destroy()
方法。
Spring用到了哪些設計模式
Spring 框架使用了多種設計模式,包括:
- 單例模式、工廠模式、抽象工廠模式、代理模式、觀察者模式、依賴注入模式、模板方法模式、策略模式、建造者模式、適配器模式、外觀模式、責任鏈模式、MVC 模式等。
這些設計模式幫助 Spring 實現了高度的解耦、靈活的擴展性、以及清晰的代碼結構。它們是 Spring 框架的核心,能夠支持復雜的企業級應用開發。
1. 單例模式 (Singleton)
- Spring 默認使用單例模式來管理 Bean,尤其是在默認的
singleton
作用域下。即 Spring 容器只會創建一個 Bean 實例,并在整個應用程序中共享該實例。- 這使得 Spring 能夠減少內存開銷,并且提供了全局共享的 Bean。
2. 工廠模式 (Factory Method)
- Spring 使用工廠模式來創建對象。Spring 容器本身就是一個工廠,負責根據配置(XML 配置或注解)創建 Bean 實例。
- 例如,
ApplicationContext
的實現類就是通過工廠方法(如getBean()
)來提供 Bean 實例。3. 抽象工廠模式 (Abstract Factory)
- Spring 通過抽象工廠模式為 Bean 的創建提供了統一的接口。比如,
BeanFactory
接口就是一個抽象工廠,負責為不同類型的 Bean 提供創建和管理的機制。- Spring 不同的實現(如
ClassPathXmlApplicationContext
,AnnotationConfigApplicationContext
)實際上都使用了抽象工廠模式來提供不同的 Bean 創建方式。4. 代理模式 (Proxy)
- Spring 使用代理模式實現了 面向切面編程 (AOP)。通過代理,Spring 能夠在方法調用前后添加增強行為,如事務管理、日志記錄等。
- JDK 動態代理和CGLIB 動態代理是 Spring 實現 AOP 的兩種主要方式。JDK 動態代理通過實現接口來代理目標對象,而 CGLIB 代理通過繼承目標類來創建代理對象。
5. 觀察者模式 (Observer)
- Spring 使用觀察者模式來實現事件發布和監聽機制。在
ApplicationContext
中,容器會發布事件,任何其他組件都可以通過實現ApplicationListener
接口來監聽和處理這些事件。- 例如,當 Spring 容器刷新或關閉時,
ContextRefreshedEvent
和ContextClosedEvent
會被觸發,監聽這些事件的類就會得到通知。6. 依賴注入模式 (Dependency Injection)
- 依賴注入 (DI) 是 Spring 的核心設計模式。通過 DI,Spring 管理 Bean 的生命周期,并自動將所需的依賴關系注入到目標對象中,避免了硬編碼的依賴關系。
- Spring 支持構造器注入、setter 注入和字段注入等多種方式來實現依賴注入。
7. 模板方法模式 (Template Method)
- Spring 的
JdbcTemplate
,HibernateTemplate
,JmsTemplate
等類是模板方法模式的應用。通過這些模板類,Spring 封裝了數據庫操作或消息隊列操作的常見流程,而用戶只需要關注業務邏輯。- 模板方法模式允許子類繼承并定制某些步驟,但保留了大部分通用操作的實現。
8. 策略模式 (Strategy)
- Spring 使用策略模式來封裝可變的行為,特別是在 AOP 和事務管理中。例如,在 Spring 中,可以通過
TransactionManager
來選擇不同的事務策略(如 JDBC 事務、JTA 事務等)。- 同樣,Spring 的各種數據訪問策略(如通過
JdbcTemplate
進行查詢操作)也是策略模式的應用。9. 建造者模式 (Builder)
- 在 Spring 中,
BeanDefinitionBuilder
就是一個典型的建造者模式示例。它幫助開發者在創建BeanDefinition
時提供更靈活的配置方式,通過一系列流式方法來構建復雜的BeanDefinition
對象。- 這種模式簡化了復雜對象的創建過程,允許開發者逐步添加配置而不需要一次性全部提供。
10. 適配器模式 (Adapter)
- Spring 的 AOP 和許多其他模塊使用了適配器模式來使不同的接口兼容。例如,Spring AOP 使用了
MethodInterceptor
來包裝被代理的方法,這個過程可以看作是一個適配器的應用,將目標方法的調用轉換為增強方法的調用。- 另外,Spring 也有很多適配器類,比如
HttpRequestHandlerAdapter
和HandlerMapping
之間的適配,幫助將不同類型的請求處理器統一接口化。11. 外觀模式 (Facade)
- Spring 通過提供簡單的接口,屏蔽了底層復雜的實現細節,幫助開發者以簡化的方式訪問復雜的業務操作。比如,
ApplicationContext
就是一個典型的外觀類,提供了訪問各種 Spring 服務的統一接口。- 外觀模式在 Spring 的集成框架中也得到了廣泛應用,例如整合數據庫、消息隊列、事務管理等操作。
12. 責任鏈模式 (Chain of Responsibility)
- Spring 使用責任鏈模式來處理某些請求的處理順序。在 Spring 的
HandlerInterceptor
和Filter
中,當請求到達時,多個處理器可以順序執行,每個處理器處理請求的不同方面(如權限檢查、日志記錄等)。- 這種模式允許多個處理者按順序處理請求,每個處理者可以決定是否繼續傳遞給下一個處理者。
13. MVC 模式 (Model-View-Controller)
- Spring 的 Web 模塊基于 MVC 模式,分離了業務邏輯(Model)、用戶界面(View)和控制邏輯(Controller)。Spring 提供了一個靈活的 MVC 框架,開發者可以定義自己的控制器、視圖解析器、數據綁定、驗證器等組件。
DispatcherServlet
作為前端控制器,處理請求并分發給合適的 Controller,最終返回視圖給用戶。
Spring Boot是如何啟動Tomcat的
- 首先,SpringBoot在啟動時會先創建一個Spring容器
- 在創建Spring容器過程中,會利用@ConditionalOnClass技術來判斷當前classpath中是否存在Tomcat依賴,如果存在則會生成一個啟動Tomcat的Bean
- Spring容器創建完之后,就會獲取啟動Tomcat的Bean,并創建Tomcat對象,并綁定端口等,然后啟動Tomcat