Spring Boot01(注解、)---java八股

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(如 devprod)來加載不同的配置。

底層實現

@Profile 是通過 Spring 環境的 @Conditional 注解機制實現的,Spring 會根據當前的運行環境選擇性地加載指定的 Bean。

11. @Transactional

作用:聲明式事務管理,標注在方法上,表示該方法需要開啟事務。Spring 會在方法執行時自動開啟事務,方法執行完成后自動提交,若出現異常則回滾。

底層實現

@Transactional 通過 AOP(面向切面編程)實現,Spring 會通過代理類在方法執行前后添加事務管理的邏輯。

Spring Boot

談談你對IOC的理解

  • IOC(Inversion of Control,控制反轉) 是一種設計原則,它的核心思想是:控制權的轉移,即不再由程序代碼顯式控制對象的創建和依賴關系,而是交給容器或框架來管理
  • 在傳統的編程方式中,開發者通常需要手動創建對象并將它們傳遞到需要使用它們的地方。而在 IOC 模式下,控制權反轉,容器會負責對象的創建、管理以及它們之間的依賴關系,這樣可以將對象的創建和使用解耦,使得程序更加靈活和易于擴展。

IOC 的優勢

  1. 解耦

    • IOC 最大的優點是降低了組件之間的耦合度。通過容器進行對象的創建和依賴注入,組件之間無需直接引用或關心對方的實現細節,只關心接口或者抽象。
    • 這使得系統更加模塊化、靈活,并且容易進行單元測試。
  2. 提高可測試性

    • 通過 IOC 容器,依賴項可以很容易地被替換和模擬。例如,可以通過 Mock 對象來測試某個組件的功能,而不需要關心其實際依賴的實現。
  3. 增強可維護性和擴展性

    • 由于對象的創建和依賴關系由容器管理,系統的修改變得更加方便。比如,如果需要替換某個服務或組件,只需修改容器配置或 Bean 定義,而不需要修改所有使用該服務的地方。
  4. 生命周期管理

    • 在傳統方式中,開發者需要手動管理對象的生命周期,如對象的初始化和銷毀。而在 IOC 中,容器會自動進行管理,從而減輕了開發者的負擔。

單例Bean和單例模式

  • 單例模式是一種設計模式,確保某個類在整個系統中只有一個實例。它適用于各種應用場景,包括需要共享資源的組件。
  • 單例 Bean是 Spring 中的一個特性,表示 Spring 容器會管理一個 Bean 并確保其在整個容器中只有一個實例。它是基于 單例模式 實現的,但通過 Spring 容器自動管理 Bean 的生命周期和依賴關系。

單例 Bean 與單例模式的區別

  1. 范圍與應用場景

    • 單例模式是一個設計模式,強調的是某個類在整個系統中只能有一個實例,通常由開發者手動控制實例的創建。
    • 單例 Bean是 Spring 中的一個概念,指的是容器管理的 Bean 在應用生命周期中只有一個實例。Spring 自動處理實例的生命周期,而開發者不需要手動實現實例控制。
  2. 實例的創建方式

    • 單例模式通常由類自身控制實例化過程,例如通過靜態方法來獲取實例。
    • 單例 Bean由 Spring 容器控制實例化過程,Spring 會自動創建該 Bean,并在整個容器中保持唯一。
  3. 線程安全

    • 單例模式中,如果實例的字段或方法不是線程安全的,可能會導致線程安全問題。開發者需要自己保證實例的線程安全性。
    • 單例 Bean通常在 Spring 中是線程安全的,但這取決于實際的 Bean 實現。在多線程環境下,Spring 會確保單例 Bean 的線程安全,但 Bean 本身的實現也需要是線程安全的。
  4. 生命周期

    • 單例模式的實例通常會在應用程序的整個生命周期內存在,開發者可以控制何時銷毀該實例。
    • 單例 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中的事務是如何實現的

  1. Spring事務底層是基于數據庫事務AOP機制
  2. 首先對于使用了@Transactional注解的Bean,Spring會創建一個代理對象作為Bean
  3. 當調用代理對象的方法時,會先判斷該方法上是否加了@Transactional注解
  4. 如果加了,那么則利用事務管理器創建一個數據庫連接
  5. 并且修改數據庫連接的autocommit屬性為false,禁止此連接的自動提交,這是實現Spring事務非常重要的一步
  6. 然后執行當前方法,方法中會執行sql
  7. 執行完當前方法后,如果沒有出現異常就直接提交事務
  8. 如果出現了異常,并且這個異常是需要回滾的就會回滾事務,否則仍然提交事務
  9. Spring事務的隔離級別對應的就是數據庫的隔離級別
  10. Spring事務的傳播機制是Spring事務自己實現的,也是Spring事務中最復雜的
  11. Spring事務的傳播機制是基于數據庫連接來做的,一個數據庫連接一個事務,如果傳播機制配置為需要新開一個事務,那么實際上就是先建立一個數據庫連接,在此新數據庫連接上執行sql

Spring中什么時候@Transactional會失效

  • 因為Spring事務是基于代理來實現的,所以某個加了@Transactional的方法只有是被代理對象調用時,那么這個注解才會生效,所以如果是被代理對象來調用這個方法,那么@Transactional是不會失效的。
  • 同時如果某個方法是private的,那么@Transactional也會失效,因為底層cglib是基于父子類來實現的,子類是不能重載父類的private方法的,所以無法很好的利用代理,也會導致@Transactianal失效

Spring容器啟動流程是怎樣的

Spring 容器啟動的流程大致可以分為以下幾個步驟:

  1. 加載配置文件或注解配置。
  2. 創建 BeanFactoryApplicationContext 實例。
  3. 掃描并解析 Bean 定義。
  4. 創建 Bean 實例并管理其生命周期。
  5. 進行依賴注入(DI)。
  6. 初始化 Bean,執行初始化方法。
  7. 發布應用上下文事件。
  8. 應用啟動完畢,可以使用容器中的 Bean。
  9. 容器關閉時,銷毀需要銷毀的 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 容器刷新或關閉時,ContextRefreshedEventContextClosedEvent 會被觸發,監聽這些事件的類就會得到通知。

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 也有很多適配器類,比如 HttpRequestHandlerAdapterHandlerMapping 之間的適配,幫助將不同類型的請求處理器統一接口化。

11. 外觀模式 (Facade)

  • Spring 通過提供簡單的接口,屏蔽了底層復雜的實現細節,幫助開發者以簡化的方式訪問復雜的業務操作。比如,ApplicationContext 就是一個典型的外觀類,提供了訪問各種 Spring 服務的統一接口。
  • 外觀模式在 Spring 的集成框架中也得到了廣泛應用,例如整合數據庫、消息隊列、事務管理等操作。

12. 責任鏈模式 (Chain of Responsibility)

  • Spring 使用責任鏈模式來處理某些請求的處理順序。在 Spring 的 HandlerInterceptorFilter 中,當請求到達時,多個處理器可以順序執行,每個處理器處理請求的不同方面(如權限檢查、日志記錄等)。
  • 這種模式允許多個處理者按順序處理請求,每個處理者可以決定是否繼續傳遞給下一個處理者。

13. MVC 模式 (Model-View-Controller)

  • Spring 的 Web 模塊基于 MVC 模式,分離了業務邏輯(Model)、用戶界面(View)和控制邏輯(Controller)。Spring 提供了一個靈活的 MVC 框架,開發者可以定義自己的控制器、視圖解析器、數據綁定、驗證器等組件。
  • DispatcherServlet 作為前端控制器,處理請求并分發給合適的 Controller,最終返回視圖給用戶。

Spring Boot是如何啟動Tomcat的

  1. 首先,SpringBoot在啟動時會先創建一個Spring容器
  2. 在創建Spring容器過程中,會利用@ConditionalOnClass技術來判斷當前classpath中是否存在Tomcat依賴,如果存在則會生成一個啟動Tomcat的Bean
  3. Spring容器創建完之后,就會獲取啟動Tomcat的Bean,并創建Tomcat對象,并綁定端口等,然后啟動Tomcat

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/70147.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/70147.shtml
英文地址,請注明出處:http://en.pswp.cn/web/70147.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

?2.快速了解HTML5的標簽類型

??HTML5 的標簽類型豐富多樣&#xff0c;每種類型都有其獨特的功能和用途&#xff0c;以下是一些常見的 HTML5 標簽類型介紹&#xff1a; &#x1f98b;結構標簽 &#x1faad;<html>&#xff1a;它是 HTML 文檔的根標簽&#xff0c;所有其他標簽都包含在這個標簽內&am…

eNSP防火墻綜合實驗

一、實驗拓撲 二、ip和安全區域配置 1、防火墻ip和安全區域配置 新建兩個安全區域 ip配置 Client1 Client2 電信DNS 百度web-1 聯通DNS 百度web-2 R2 R1 三、DNS透明代理相關配置 1、導入運營商地址庫 2、新建鏈路接口 3、配置真實DNS服務器 4、創建虛擬DNS服務器 5、配置D…

Linux 配置交換空間(Swap)解決內存不足

&#x1f680; 作者主頁&#xff1a; 有來技術 &#x1f525; 開源項目&#xff1a; youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template &#x1f33a; 倉庫主頁&#xff1a; GitCode︱ Gitee ︱ Github &#x1f496; 歡迎點贊 &#x1f44d; 收藏 ?評論 …

個人shell腳本分享

在周一到周五做增量備份&#xff0c;在周六周日做完全備份 #!/bin/bash定義變量 SRC“/path/to/source” # 源目錄 BKUP“/backup” # 備份主目錄 FUL“KaTeX parse error: Expected EOF, got # at position 22: …ull" #? 完全備份目錄 INC"BKUP/inc” # 增量備份…

Django 5 實用指南(一)安裝與配置

1.1 Django5的背景與發展 Django 自從2005年由Adrian Holovaty和Simon Willison在 Lawrence Journal-World 新聞網站上首次發布以來&#xff0c;Django 一直是 Web 開發領域最受歡迎的框架之一。Django 框架經歷了多個版本的演進&#xff0c;每次版本更新都引入了新功能、改進了…

百度搜索融合 DeepSeek 滿血版,開啟智能搜索新篇

百度搜索融合 DeepSeek 滿血版&#xff0c;開啟智能搜索新篇 &#x1f680; &#x1f539; 一、百度搜索全量接入 DeepSeek &#x1f539; 百度搜索迎來重要升級&#xff0c;DeepSeek 滿血版全面上線&#xff01;&#x1f389; 用戶在百度 APP 搜索后&#xff0c;點擊「AI」即…

RabbitMQ服務異步通信

消息隊列在使用過程中&#xff0c;面臨著很多實際問題需要思考&#xff1a; 1. 消息可靠性 消息從發送&#xff0c;到消費者接收&#xff0c;會經理多個過程&#xff1a; 其中的每一步都可能導致消息丟失&#xff0c;常見的丟失原因包括&#xff1a; 發送時丟失&#xff1a; 生…

【教程】MySQL數據庫學習筆記(七)——多表操作(持續更新)

寫在前面&#xff1a; 如果文章對你有幫助&#xff0c;記得點贊關注加收藏一波&#xff0c;利于以后需要的時候復習&#xff0c;多謝支持&#xff01; 【MySQL數據庫學習】系列文章 第一章 《認識與環境搭建》 第二章 《數據類型》 第三章 《數據定義語言DDL》 第四章 《數據操…

膠囊網絡動態路由算法:突破CNN空間局限性的數學原理與工程實踐

一、CNN的空間局限性痛點解析 傳統CNN的瓶頸&#xff1a; 池化操作導致空間信息丟失&#xff08;最大池化丟棄85%激活值&#xff09;無法建模層次空間關系&#xff08;旋轉/平移等變換不敏感&#xff09;局部感受野限制全局特征整合 示例對比&#xff1a; # CNN最大池化示例…

#滲透測試#批量漏洞挖掘#Apache Log4j反序列化命令執行漏洞

免責聲明 本教程僅為合法的教學目的而準備,嚴禁用于任何形式的違法犯罪活動及其他商業行為,在使用本教程前,您應確保該行為符合當地的法律法規,繼續閱讀即表示您需自行承擔所有操作的后果,如有異議,請立即停止本文章讀。 目錄 Apache Log4j反序列化命令執行漏洞 一、…

深入剖析Spring MVC

一、Spring MVC 概述 1. 什么是 Spring MVC&#xff1f; Spring MVC 是基于 Spring 框架的 Web 框架&#xff0c;它實現了 MVC 設計模式&#xff0c;將應用程序分為三個核心部分&#xff1a; Model&#xff1a;封裝應用程序的數據和業務邏輯。 View&#xff1a;負責渲染數據…

機器學習入門-讀書摘要

先看了《深度學習入門&#xff1a;基于python的理論和實踐》這本電子書&#xff0c;早上因為入迷還坐過站了。。 因為里面的反向傳播和鏈式法則特別難懂&#xff0c;又網上搜了相關內容進行進一步理解&#xff0c;參考的以下文章&#xff08;個人認為都講的都非常好&#xff0…

【AI】mac 本地部署 Dify 實現智能體

下載 Ollama 訪問 Ollama 下載頁&#xff0c;下載對應系統 Ollama 客戶端。或者參考文章【實戰AI】macbook M1 本地ollama運行deepseek_m1 max可以跑deepseek嗎-CSDN博客 dify 開源的 LLM 應用開發平臺。提供從 Agent 構建到 AI workflow 編排、RAG 檢索、模型管理等能力&am…

[實現Rpc] 消息抽象層的具體實現

目錄 具象層 _ 消息抽象的實現 信息的抽象類 實現 JsonMessage JsonRequest & JsonResponse 消息-不同消息分裝實現 實現 Request RpcRequest TopicRequest ServiceRequest Response RpcResponse TopicResponse ServiceResponse 實現 生產工廠 本篇文章繼 …

計算機考研之數據結構:深入解析最大公約數與歐幾里得算法

一、生活中的公約數應用 在日常生活中&#xff0c;經常需要處理"均分分配"問題。例如&#xff1a;要將24塊巧克力和18塊餅干平均分給小朋友&#xff0c;最多能分給幾個小朋友&#xff1f;這就是典型的求最大公約數問題。 二、基本概念詳解 約數與公約數 約數&…

NCHAR_CS和CHAR_CS,導致UNION ALL 時,提示SQL 錯誤 [12704] [72000]: ORA-12704: 字符集不匹配

檢查涉及的數據表和列的字符集設置 -- 查詢表的字符集 SELECT parameter, value FROM nls_database_parameters WHERE parameter LIKE NLS_CHARACTERSET;-- 查詢列的字符集&#xff08;對于特定表&#xff09; SELECT column_name, character_set_name FROM all_tab_columns W…

算法之 跳躍游戲

文章目錄 55.跳躍游戲思路參考&#xff1a;56.合并區間 55.跳躍游戲 55.跳躍游戲 靈神思路 思路分析&#xff1a; 兩種思路&#xff0c;思路1是我們可以直接維護當前到達i的時候所能到達的最右的邊界mr&#xff0c;如果i>mr就說明無法到達i,否則就是可以到達&#xff1b;…

在C#中動態訪問對象屬性時,用表達式樹可以獲得高效性能

在C#中如何用表達式樹動態訪問對象屬性的問題。用戶可能已經知道反射的基本用法&#xff0c;但想用表達式樹來提高性能&#xff0c;因為表達式樹編譯后的委托執行速度比反射快。 首先&#xff0c;表達式樹的基本概念。表達式樹允許在運行時構建代碼&#xff0c;并編譯成可執行的…

深入解析 Flutter 性能優化:從原理到實踐

深入解析 Flutter 性能優化&#xff1a;從原理到實踐的全面指南 Flutter 是一個高性能的跨平臺框架&#xff0c;但在開發復雜應用時&#xff0c;性能問題仍然可能出現。性能優化是開發高質量 Flutter 應用的關鍵。本篇博客將從 Flutter 的渲染原理出發&#xff0c;結合實際場景…

使用 Python 爬蟲獲取微店快遞費用 item_fee API 接口數據

在電商運營中&#xff0c;快遞費用是影響商家利潤和用戶體驗的重要因素之一。微店作為國內知名的電商平臺&#xff0c;提供了豐富的 API 接口供開發者使用&#xff0c;其中也包括查詢商品快遞費用的接口。通過調用微店的 item_fee 接口&#xff0c;開發者可以獲取指定商品的快遞…