【SpringBoot】05 容器功能 - SpringBoot底層注解的應用與實戰 - @Configuration + @Bean

文章目錄

  • 前言
  • 一、創建兩個組件
  • 二、使用傳統方式
    • 源代碼
    • 解釋
  • 三、使用SpringBoot方法
    • 源代碼
    • 解釋
  • 四、查看是否添加到組件中
    • 查看
    • 自定義組件名
    • 配置類在容器中注冊的是單實例組件
    • 配置類本身也是容器中的一個組件
    • Configuration的proxyBeanMethods屬性:代理bean的方法
      • `proxyBeanMethods` 參數詳解
      • 詳細說明
      • 1. `proxyBeanMethods = true`(默認)
      • 2. `proxyBeanMethods = false`
      • 選擇建議
  • 總結


前言

@Configuration // 告訴 SpringBoot 這是一個配置類 == 配置文件
@Bean // 給容器中添加組件。以方法名作為組件的id,返回類型就是組件類型。返回的值,就是組件在容器中的實例
@Bean(“tom123”) // 給容器中添加組件。以方法名作為組件的id,返回類型就是組件類型。返回的值,就是組件在容器中的實例

IOC 容器(Inversion of Control Container)是實現 控制反轉 思想的一個運行期框架組件,用來集中創建、裝配、管理對象(Bean)及其生命周期。
一句話:原來由程序代碼 new 的對象,現在統一交給容器“注入”進來,代碼只聲明“我需要什么”,而不關心“怎么得到”。

  • 控制反轉(IoC):對象創建與依賴綁定的“控制權”從業務代碼反轉到容器。
  • 依賴注入(DI):容器把依賴對象“注入”到需要它的地方,常見方式:
    • 構造函數注入
    • Setter 注入
    • 字段/注解注入
// 聲明組件
@Component
public class OrderService { }@RestController
public class OrderController {@Autowired          // 容器注入private OrderService service;
}

啟動 Spring 后,容器掃描注解 → 創建 OrderService → 注入 OrderController,全程無 new。

一、創建兩個組件

我們先創建兩個組件User和Pet,也就是兩個類,放在bean包里面。

在這里插入圖片描述

package com.hello.bean;/*** 用戶*/public class User { // 要把這兩個組件添加到容器中private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}// 添加帶參數的構造方法public User(String name, Integer age){this.name = name;this.age = age;}@Overridepublic String toString() {return "User [name=" + name + ", age=" + age + "]";}}
package com.hello.bean;/*** 寵物*/
public class Pet {private String name;public String getName(){return name;};public void setName(String name){this.name = name;}// 添加構造器public Pet() { // 無參構造器}public Pet(String name) { // 帶參構造器this.name = name;}@Overridepublic String toString() {return "Pet{" +"name='" + name + '\'' +'}';}
}

二、使用傳統方式

要添加到容器中,首先在資源文件夾中新建beans.xml文件,然后進行組件的添加。

在這里插入圖片描述

源代碼

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.hello.bean.User"><property name="name" value="zhangsan"></property><property name="age" value="18"></property></bean><bean id="cat" class="com.hello.bean.Pet"><property name="name" value="tomcat"></property></bean>
</beans>

解釋

這個XML文件是一個典型的Spring框架配置文件,用于定義和配置Spring容器中的Bean。下面是對這個配置文件的詳細解釋:

  1. XML聲明和命名空間

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    • 第一行是標準的XML聲明
    • 定義了beans根元素和Spring的命名空間
    • 指定了XML Schema定義文件的位置
  2. User Bean定義

    <bean id="user" class="com.hello.bean.User"><property name="name" value="zhangsan"></property><property name="age" value="18"></property>
    </bean>
    
    • 定義了一個ID為"user"的Bean
    • 類路徑為com.hello.bean.User
    • 設置了兩個屬性:
      • name屬性值為"zhangsan"
      • age屬性值為18
  3. Pet Bean定義

    <bean id="cat" class="com.hello.bean.Pet"><property name="name" value="tomcat"></property>
    </bean>
    
    • 定義了一個ID為"cat"的Bean
    • 類路徑為com.hello.bean.Pet
    • 設置了name屬性值為"tomcat"
  4. 配置特點

    • 使用了setter注入方式(通過<property>元素)
    • 注入的都是簡單值(String和int)
    • 沒有定義Bean之間的依賴關系
  5. 對應的Java類結構
    假設的User類:

    package com.hello.bean;public class User {private String name;private int age;// 必須有setter方法public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}
    }
    

    假設的Pet類:

    package com.hello.bean;public class Pet {private String name;public void setName(String name) {this.name = name;}
    }
    
  6. 使用場景

    • 這種配置方式在傳統的Spring XML配置中很常見
    • 適用于簡單的Bean定義和屬性注入
    • 在現代Spring Boot應用中,這種配置方式通常被注解配置(如@Component@Configuration)取代

注意:要使這個配置正常工作,對應的Java類必須有無參構造函數和相應的setter方法,因為這里使用的是setter注入方式。

三、使用SpringBoot方法

新建config.MyConfig類,在其中寫入代碼:

源代碼

package com.hello.config;import com.hello.bean.User;
import com.hello.bean.Pet;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration // 告訴 SpringBoot 這是一個配置類 == 配置文件
public class MyConfig {@Bean // 給容器中添加組件。以方法名作為組件的id,返回類型就是組件類型。返回的值,就是組件在容器中的實例public User user01() {return new User("zhangsan", 18);}@Bean // 給容器中添加組件。以方法名作為組件的id,返回類型就是組件類型。返回的值,就是組件在容器中的實例public Pet cat(){return new Pet("tomcat");}
}

解釋

使用 Java 配置類替代 XML 配置的 Spring Boot 配置示例,下面是對這段代碼的詳細解釋:

  1. 類級別注解
@Configuration // 告訴 SpringBoot 這是一個配置類 == 配置文件
public class MyConfig {
  • @Configuration 注解標識這是一個 Spring 配置類,相當于 XML 配置文件
  • 配置類中可以定義多個 @Bean 方法,用于向 Spring 容器注冊組件
  1. User Bean 定義
@Bean // 給容器中添加組件
public User user01() {return new User("zhangsan", 18);
}
  • @Bean 注解表示該方法會返回一個對象,該對象要注冊到 Spring 容器中
  • 默認情況下,Bean 的名稱(ID)就是方法名 user01
  • 這里創建了一個 User 對象,使用構造器注入方式設置 name=“zhangsan” 和 age=18
  1. Pet Bean 定義
@Bean // 給容器中添加組件
public Pet cat(){return new Pet("tomcat");
}
  • 同樣使用 @Bean 注解,Bean 的名稱為 cat
  • 創建了一個 Pet 對象,設置 name=“tomcat”
  1. 與 XML 配置的對比

    • 等效于之前的 XML 配置,但使用了更現代的 Java 配置方式
    • 不需要 setter 方法,直接使用構造器注入
    • 類型安全,編譯器可以檢查類型錯誤
    • 可以方便地添加邏輯(如條件判斷等)
  2. 對應的 Java 類結構
    假設的 User 類(需要對應的構造器):

package com.hello.bean;public class User {private String name;private int age;public User(String name, int age) {this.name = name;this.age = age;}
}

假設的 Pet 類:

package com.hello.bean;public class Pet {private String name;public Pet(String name) {this.name = name;}
}
  1. 使用特點

    • 這是 Spring Boot 推薦的首選配置方式
    • 配置類本身也是一個 Spring 組件(@Configuration@Component 的派生注解)
    • 可以方便地與其他 Spring 特性(如 @Profile, @Conditional 等)結合使用
    • 支持方法間調用(Spring 會攔截確保單例)
  2. 獲取這些 Bean
    在應用中可以通過以下方式獲取:

// 通過類型獲取
User user = applicationContext.getBean(User.class);// 通過名稱獲取
Pet pet = (Pet) applicationContext.getBean("cat");

這種基于 Java 的配置方式比 XML 更類型安全、更靈活,是現代 Spring Boot 應用的主要配置方式。

四、查看是否添加到組件中

查看

在主程序中進行容器IOC中所有組件的輸出。
在這里插入圖片描述

可以搜到對應的組件,說明組件已經添加成功。
在這里插入圖片描述

自定義組件名

可以通過@Bean(“tom123”) 這樣的方式自定義組件名,這樣添加組件名稱就是不是默認的方法名。

  @Bean("tom123") // 給容器中添加組件。以方法名作為組件的id,返回類型就是組件類型。返回的值,就是組件在容器中的實例public Pet cat(){return new Pet("tomcat");}

我們來進行組件名的輸出,點啟動項目。在控制臺觀察、搜索添加的組件。

 public static void main(String[] args) {// 1、返回我們IOC容器ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);// 2、查看容器里面的所有組件String[] names = run.getBeanDefinitionNames();for (String name : names){System.out.println(name);}// 3、從容器中獲取組件// 拼接最終啟動成功信息String successMessage ="🎉 **啟動成功!** (ノ?ヮ?)ノ*:・゚?\n" +"? *服務已就緒,端口 8083* ?\n" +"💻 訪問地址:`http://localhost:8083`\n" +"💪 **Go! Go! Go!** (? ?_?)?";System.out.println(successMessage);}

在這里插入圖片描述
這樣我們就給容器中注入了兩個組件。

配置類在容器中注冊的是單實例組件

package com.hello.config;import com.hello.bean.User;
import com.hello.bean.Pet;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 配置類里面使用@Bean標注在方法上給容器中添加組件,默認是單實例的*/
@Configuration // 告訴 SpringBoot 這是一個配置類 == 配置文件
public class MyConfig {@Bean // 給容器中添加組件。以方法名作為組件的id,返回類型就是組件類型。返回的值,就是組件在容器中的實例public User user01() {return new User("zhangsan", 18);}@Bean("tom123") // 給容器中添加組件。以方法名作為組件的id,返回類型就是組件類型。返回的值,就是組件在容器中的實例public Pet cat(){return new Pet("tomcat");}
}

我們可以來讀取組件對象進行驗證一下。

// 3、從容器中獲取組件Pet tom1 = run.getBean("tom123", Pet.class);Pet tom2 = run.getBean("tom123", Pet.class);System.out.println("兩個組件是否相同" + (tom1 == tom2));

在這里插入圖片描述

配置類本身也是容器中的一個組件

當時一個類名上加了@Configuratio以后,這個類也會被加入到容器中,作為一個組件。

驗證:

MyConfig bean = run.getBean(MyConfig.class);System.out.println(bean);

在這里插入圖片描述

Configuration的proxyBeanMethods屬性:代理bean的方法

應用場景:解決組件依賴問題。

 * 3、proxyBeanMethods:代理bean的方法*  full: 全量模式,IOC容器啟動時,會創建所有的單實例Bean(true)*  light: 輕量模式,IOC容器啟動時,不會創建單實例Bean,而是當調用getBean方法時,才會創建Bean(false)

proxyBeanMethods 參數詳解

proxyBeanMethods@Configuration 注解中的一個重要屬性,它決定了配置類中 @Bean 方法是否被代理。下面是它的取值含義表格:

含義適用場景性能影響容器行為
true (默認值)啟用代理,確保 @Bean 方法調用總是返回相同的實例(單例)需要保證單例的場景,方法間有依賴關系時有輕微性能開銷(CGLIB代理)Spring會攔截方法調用,檢查容器中是否已存在該Bean
false禁用代理,直接調用方法不需要方法間依賴,或追求啟動速度的場景無代理開銷,啟動更快每次調用方法都會真正執行,不保證單例

詳細說明

1. proxyBeanMethods = true(默認)

@Configuration(proxyBeanMethods = true)
public class MyConfig {@Beanpublic User user() {return new User(pet()); // 無論調用多少次,返回的都是同一個Pet實例}@Bean public Pet pet() {return new Pet("tomcat");}
}
  • 特點:方法間調用會被Spring攔截,確保單例
  • 優點:保證Bean的單例性,方法間依賴安全
  • 缺點:有CGLIB代理開銷

2. proxyBeanMethods = false

@Configuration(proxyBeanMethods = false)
public class MyConfig {@Beanpublic User user() {return new User(pet()); // 每次調用都會new新的Pet實例}@Bean public Pet pet() {return new Pet("tomcat");}
}
  • 特點:相當于普通Java方法調用
  • 優點:無代理開銷,啟動更快
  • 缺點:不能保證方法間調用的單例性

選擇建議

考慮因素推薦設置
配置類中的@Bean方法需要相互調用true
需要嚴格的單例保證true
追求應用啟動速度false
配置類中沒有方法間調用false
Spring Boot 2.2+ 的@Configuration通常設為false

在Spring Boot 2.2+中,很多場景下推薦使用proxyBeanMethods = false以提高性能,特別是大型應用。

總結

本文全面對比了Spring Boot中兩種主要的組件配置方式:傳統XML配置和現代Java配置類方式,并深入分析了@Configuration@Bean注解的核心特性。

  1. 配置方式演進

    • XML配置是傳統Spring的經典方式,通過<bean>標簽定義組件,依賴setter注入
    • Java配置類是現代Spring Boot推薦方式,使用@Configuration@Bean注解,更類型安全靈活
  2. 注解核心功能

    • @Configuration標記配置類,替代XML配置文件
    • @Bean注解方法向容器注冊組件,默認單例,方法名作為組件ID
    • 支持自定義組件名(@Bean("name"))和方法間依賴調用
  3. 高級特性

    • proxyBeanMethods參數控制代理行為,平衡單例保證與性能
    • 配置類本身也是容器組件,可通過上下文獲取
    • 與各種條件注解(@Conditional等)無縫集成
  4. 實踐建議

    • 新項目優先使用Java配置類方式
    • 簡單場景可設置proxyBeanMethods=false提升性能
    • 需要嚴格單例和方法間依賴時保持默認true
    • 合理命名組件ID提高可讀性

現代Spring Boot應用開發中,基于注解的配置方式憑借其類型安全、代碼導航方便和與Java語言的天然契合等優勢,已成為事實標準。理解這些核心配置機制,是掌握Spring Boot自動配置原理的基礎,也是進行高效應用開發的關鍵。

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

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

相關文章

c#聯合Halcon進行OCR字符識別(含halcon-25.05 百度網盤)

1.下載安裝halcon 通過網盤分享的文件&#xff1a;halcon-25.05.0.0-x64-win64 鏈接: https://pan.baidu.com/s/1XAx-8ZQM-ZHkgHIc-dhCYw 提取碼: whek 2.c#環境配置 創建test_halcon_ocr項目 找到halcon的安裝路徑 我的&#xff1a; D:\halcon\HALCON-25.05-Progress\bin\x64…

絲桿支撐座怎樣助力升降設備實現智能化?

絲桿支撐座作為傳動系統中的關鍵支撐部件&#xff0c;憑借其高剛性、抗沖擊及精準定位能力&#xff0c;廣泛應用于重型機械與升降設備領域&#xff0c;為設備提供穩定可靠的軸向承載與徑向支撐&#xff0c;確保高負荷工況下的安全運行。電梯 / 升降平臺&#xff1a;液壓電梯的輔…

Notta:高效智能的音頻轉文字工具

本文轉載自&#xff1a;Notta&#xff1a;高效智能的音頻轉文字工具 - Hello123 ** 一、產品簡介 Notta 是一款基于 AI 語音識別引擎的語音轉文字工具&#xff0c;支持 58 種語言的轉錄和 42 種語言的翻譯。用戶可通過實時錄音或上傳音頻 / 視頻文件&#xff08;如 MP3、WAV …

Docker私有倉庫創建及Docky存儲與網絡配置(小白的“升級打怪”成長之路)

目錄 一、Docker私有倉庫創建 1、在一臺安裝Docker私有倉庫的主機上添加docker-compose 命令 2、安裝docker-ce服務 3、Docker 鏡像加速 4、安裝Harbor倉庫 5、使用腳本安裝倉庫 6、網站登陸 7、客戶端使用Harbor倉庫 二、Docky存儲與網絡配置 1、存儲與網絡 掛載主機…

谷歌ADK接入文件操作MCP

文章目錄MCP基礎概念文件操作服務器文件操作MCP接入谷歌ADK項目創建多輪對話代碼MCP基礎概念 MCP技術體系中&#xff0c;會將外部工具運行腳本稱作服務器&#xff0c;而接入這些外部工具的大模型運行環境稱作客戶端。 一個客戶端可以接入多個不同類型的服務器&#xff0c;但都…

高光譜技術的獨特優勢

高光譜技術憑借其?納米級連續光譜采集能力?和?圖譜合一的探測模式?&#xff0c;在多個領域展現出不可替代的獨特優勢&#xff1a;一、光譜維度&#xff1a;精細物質指紋識別?納米級連續光譜解析? 通過 ?5-10nm帶寬的數百個連續波段?&#xff08;最高330個通道&#xff…

基于Vue+Element UI集成高德地圖的完整實踐指南

本次開發使用deepseek 簡直如虎添翼得心應手 生成模擬數據、解決報錯那真是嘎嘎地 在 Vue Element UI 項目中引入高德地圖 具體實現步驟&#xff1a; 高德開放平臺&#xff1a;注冊賬號 → 進入控制臺 → 創建應用 → 獲取 Web端(JS API)的Key https://lbs.amap.com/ 這里需要…

Day50--圖論--98. 所有可達路徑(卡碼網),797. 所有可能的路徑

Day50–圖論–98. 所有可達路徑&#xff08;卡碼網&#xff09;&#xff0c;797. 所有可能的路徑 刷今天的內容之前&#xff0c;要先去《代碼隨想錄》網站&#xff0c;先看完&#xff1a;圖論理論基礎和深度優先搜索理論基礎。做完之后可以看題解。有余力&#xff0c;把廣度優先…

Python 異常捕獲

一、獲取未知錯誤try:# 相關處理邏輯 異常后面輸出print(輸入信息……) except Exception as e:print(未知錯誤,e)二、獲取已知錯誤except 錯誤單詞&#xff08;來源于錯誤信息的第一個單詞&#xff09;多個已知錯誤使用 except XXXXX:try:# 相關處理邏輯 異常后面輸出print…

RIOT、RT-Thread 和 FreeRTOS 是三種主流的實時操作系統

RIOT、RT-Thread 和 FreeRTOS 是三種主流的實時操作系統&#xff08;RTOS&#xff09;&#xff0c;專為嵌入式系統和物聯網&#xff08;IoT&#xff09;設備設計。它們在架構、功能、生態和應用場景上有顯著差異&#xff0c;以下是詳細對比&#xff1a;1. 架構與設計理念特性RI…

【FAQ】Win11創建資源不足繞開微軟賬號登錄

Win11安裝資源限制 因為 Windows 11 有兩項強制檢測 VMware 8 默認沒提供&#xff1a; TPM 2.0&#xff08;可信平臺模塊&#xff09;Secure Boot&#xff08;安全啟動&#xff09; 一步到位解決辦法&#xff08;官方兼容方式&#xff09; 關閉虛擬機電源編輯虛擬機設置 選項 →…

Docker使用----(安裝_Windows版)

一、Docker Docker 鏡像就像是一個軟件包&#xff0c;里面包括了應用程序的代碼、運行所需的庫和工具、配置文件等等&#xff0c;所有這些都打包在一起&#xff0c;以確保應用程序在不同的計算機上運行時&#xff0c;都能保持一致性。 可以把 Docker 鏡像想象成一個軟件安裝文件…

91、23種經典設計模式

設計模式是軟件設計中反復出現的解決方案的模板&#xff0c;用于解決特定問題并提高代碼的可維護性、可擴展性和可復用性。23種經典設計模式可分為創建型、結構型和行為型三大類&#xff0c;以下是具體分類及模式概述&#xff1a; 一、創建型模式&#xff08;5種&#xff09; 關…

Illustrator總監級AI魔法:一鍵讓低清logo變矢量高清,徹底告別手動描摹!

在海外從事設計十幾年&#xff0c;我敢說&#xff0c;每個設計師都經歷過一種“史詩級”的折磨&#xff1a;客戶發來一個像素低得感人、邊緣模糊不清的JPG格式Logo&#xff0c;然后要求你把它用在巨幅海報或者高清視頻上。這意味著什么&#xff1f;意味著我們要打開Illustrator…

各種 dp 刷題下

6.#8518 杰瑞征途 / 洛谷 P4072 征途 題意 Pine 開始了從 SSS 地到 TTT 地的征途。從 SSS 地到 TTT 地的路可以劃分成 nnn 段&#xff0c;相鄰兩段路的分界點設有休息站。Pine 計劃用 mmm 天到達 TTT 地。除第 mmm 天外&#xff0c;每一天晚上 Pine 都必須在休息站過夜。所以…

本地WSL部署接入 whisper + ollama qwen3:14b 總結字幕增加利用 Whisper 分段信息,全新 Prompt功能

1. 實現功能 M4-3: 智能后處理 - 停頓感知增強版 (終極版) 本腳本是 M4-3 的重大升級&#xff0c;引入了“停頓感知”能力&#xff1a; 利用 Whisper 分段信息: 將 Whisper 的 segments 間的自然停頓作為強信號 ([P]) 提供給 LLM。全新 Prompt: 設計了專門的 Prompt&#xff0c…

微算法科技(NASDAQ:MLGO)開發經典增強量子優化算法(CBQOA):開創組合優化新時代

近年來&#xff0c;量子計算在組合優化領域的應用日益受到關注&#xff0c;各類量子優化算法層出不窮。然而&#xff0c;由于現階段量子硬件的局限性&#xff0c;如何充分利用已有的經典計算能力來增強量子優化算法的表現&#xff0c;成為當前研究的重要方向。基于此&#xff0…

功能、延遲、部署、成本全解析:本地化音視頻 SDK 對比 云端方案

引言 在構建實時音視頻系統時&#xff0c;技術選型往往決定了項目的天花板。開發者面臨的第一個關鍵抉擇&#xff0c;就是是選擇完全可控的本地化音視頻內核&#xff0c;還是依賴云廠商的實時音視頻服務。 以大牛直播SDK&#xff08;SmartMediaKit&#xff09;為代表的本地部…

微調入門:為什么微調

歡迎來到啾啾的博客&#x1f431;。 記錄學習點滴。分享工作思考和實用技巧&#xff0c;偶爾也分享一些雜談&#x1f4ac;。 有很多很多不足的地方&#xff0c;歡迎評論交流&#xff0c;感謝您的閱讀和評論&#x1f604;。 目錄1 什么時候我們需要微調呢&#xff1f;1.1 微調的…

3、匹配一組字符

在本章里&#xff0c;你將學習如何與字符集合打交道。與可以匹配任意單個字符的.字符&#xff08;參見第2章&#xff09;不同&#xff0c;字符集合能匹配特定的字符和字符區間。3.1 匹配多個字符中的某一個第2章介紹的.?字符&#xff0c;可以匹配任意單個字符。當時在最后一個…