Spring 創建 Bean 的 8 種主要方式

Spring(尤其是 Spring Boot)提供了多種方式來讓容器創建和管理 Bean。@Component@Configuration + @Bean@EnableConfigurationProperties 都是常見方式。

下面我為你系統地梳理 Spring 創建 Bean 的所有主要方式,并說明它們的使用場景和區別。


? 一、Spring 創建 Bean 的 8 種主要方式

方式注解/方法適用場景
1@Component 及其衍生注解掃描普通類為 Bean
2@Configuration + @Bean手動配置第三方類或復雜對象
3@EnableConfigurationProperties + @ConfigurationProperties將配置文件映射為 Bean
4@Import導入配置類或直接注冊 Bean
5實現 FactoryBean<T>創建復雜或條件性對象
6使用 @Conditional 系列注解條件化注冊 Bean
7編程式注冊:BeanDefinitionRegistryPostProcessor動態注冊 Bean(高級)
8XML 配置(傳統方式)老項目兼容

1. @Component 及其衍生注解(最常用)

@Component
@Service
@Repository
@Controller
@RestController
@Configuration // @Configuration 也是 @Component
  • 原理:配合 @ComponentScan,Spring 會掃描這些類并注冊為 Bean。
  • 適用:你自己寫的業務類(Service、DAO、Controller 等)。
@Service
public class UserService {public void save() { ... }
}

? 自動注冊為 userService Bean。


2. @Configuration + @Bean(手動注冊)

用于注冊不能加 @Component 的類(如第三方庫的類)。

@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);return template;}
}
  • 適用:數據源、RedisTemplate、RabbitMQ、RocketMQ、OkHttp、HttpClient 等第三方組件。

3. @EnableConfigurationProperties + @ConfigurationProperties

application.yml 中的配置自動綁定為 Bean。

app:title: MyAppversion: 1.0.0
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {private String title;private String version;// getter/setter
}
@Configuration
@EnableConfigurationProperties(AppProperties.class)
public class AppConfig {
}

? AppProperties 會被 Spring 創建并注入配置值,且可被 @Autowired

💡 在 Spring Boot 2.2+ 中,@EnableConfigurationProperties 通常可以省略,只要類加了 @ConfigurationProperties 并被掃描到即可。


4. @Import(導入配置類或直接注冊)

三種用法:

(1) 導入 @Configuration
@Import(DatabaseConfig.class)
@SpringBootApplication
public class Application { }
(2) 導入 @Component
@Import(UserService.class)
(3) 導入 ImportSelectorImportBeanDefinitionRegistrar
@Import(MyImportSelector.class)
public class Application { }public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{MyService.class.getName()};}
}

? 用于實現“條件導入”、“SPI 擴展”等高級功能。


5. 實現 FactoryBean<T>(創建復雜對象)

當你需要復雜的創建邏輯時使用。

public class MyFactoryBean implements FactoryBean<MyService> {@Overridepublic MyService getObject() throws Exception {MyService service = new MyService();service.init(); // 復雜初始化return service;}@Overridepublic Class<?> getObjectType() {return MyService.class;}@Overridepublic boolean isSingleton() {return true;}
}
@Component
public class MyFactoryBean { } // Spring 會調用 getObject() 創建 MyService Bean

? 適合創建代理對象、動態對象、SPI 實現等。


6. @Conditional 系列注解(條件化注冊)

只有滿足條件時才創建 Bean。

@Bean
@ConditionalOnMissingBean(DataSource.class)
public DataSource dataSource() {return new HikariDataSource();
}

常見條件注解:

注解說明
@ConditionalOnClass類路徑存在某個類
@ConditionalOnMissingBean容器中沒有某個 Bean
@ConditionalOnProperty配置文件中有某個屬性
@ConditionalOnWebApplication是 Web 應用
@ConditionalOnExpressionSpEL 表達式為 true

? 這是 Spring Boot 自動配置的核心機制。


7. 編程式注冊:BeanDefinitionRegistryPostProcessor

最強大、最靈活的方式,可以在容器啟動時動態注冊 Bean。

@Component
public class DynamicBeanRegistrar implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(UserService.class);AbstractBeanDefinition definition = builder.getBeanDefinition();registry.registerBeanDefinition("userService", definition);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {// do nothing}
}

? 適合插件化、動態加載、AOP 增強等場景。


8. XML 配置(傳統方式)

<bean id="userService" class="com.example.UserService"/>
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

? 現在已不推薦,但在老項目中仍可見。


? 總結對比

方式何時使用推薦度
@Component自己寫的類?????
@Configuration + @Bean第三方類、復雜配置?????
@ConfigurationProperties配置文件映射????
@Import模塊化導入???
FactoryBean復雜對象創建???
@Conditional條件注冊????(自動配置核心)
BeanDefinitionRegistryPostProcessor動態注冊??(高級)
XML老項目?

? 最佳實踐建議

  1. 優先使用 @Component@Bean,簡單直接;
  2. 配置參數用 @ConfigurationProperties,類型安全;
  3. 避免重復注冊,善用 @ConditionalOnMissingBean
  4. 復雜邏輯用 @ImportFactoryBean
  5. 動態場景用 BeanDefinitionRegistryPostProcessor(謹慎使用)。

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

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

相關文章

React 第七十節 Router中matchRoutes的使用詳解及注意事項

前言 matchRoutes 是 React Router v6 提供的一個核心工具函數&#xff0c;主要用于匹配路由配置與當前路徑。它在服務端渲染&#xff08;SSR&#xff09;、數據預加載、權限校驗等場景中非常實用。下面詳細解析其用法、注意事項和案例分析&#xff1a; 1、基本用法 import { m…

iSCSI服務配置全指南(含服務器與客戶端)

iSCSI服務配置全指南&#xff08;含服務器與客戶端&#xff09;一、iSCSI簡介 1. 概念 互聯網小型計算機系統接口&#xff08;Internet Small Computer System Interface&#xff0c;簡稱iSCSI&#xff09;是一種基于TCP/IP的協議&#xff0c;其核心功能是通過IP網絡仿真SCSI高…

堆(Heap):高效的優先級隊列實現

什么是堆&#xff1f;堆是一種特殊的完全二叉樹&#xff0c;滿足以下性質&#xff1a;堆序性&#xff1a;每個節點的值與其子節點滿足特定關系最小堆&#xff1a;父節點 ≤ 子節點&#xff08;根最小&#xff09;最大堆&#xff1a;父節點 ≥ 子節點&#xff08;根最大&#xf…

朝花夕拾(四) --------python中的os庫全指南

目錄 Python os模塊完全指南&#xff1a;從基礎到高階文件操作 1. 引言&#xff1a;為什么需要os模塊&#xff1f; 1.1 os模塊的重要性 1.2 適用場景 1.3 os模塊的"瑞士軍刀"特性 2. os模塊基礎功能 2.1 文件與目錄操作 2.1.1 核心方法介紹 2.1.2 避坑指南 …

uniappx 安卓端本地打包的一些總結

本人之前沒用過android studio&#xff0c;因為有打包到安卓端的需求&#xff0c;所以有了這篇文章。下面一些內容不正常工作&#xff0c;也不報錯&#xff0c;是很煩的&#xff0c;根本不知道是哪里出了問題。比如對應的aar包沒有引入。或者沒有注冊信息。 在實現過程中我遇到…

AUTOSAR進階圖解==>AUTOSAR_SWS_UDPNetworkManagement

AUTOSAR UDP網絡管理詳解 基于AUTOSAR標準的UDP網絡管理模塊架構分析與實現指南目錄 1. 概述2. UDP網絡管理架構 2.1 整體架構圖2.2 架構組件詳解 3. UDP網絡管理狀態機 3.1 狀態機圖3.2 狀態詳解 4. UDP網絡管理操作序列 4.1 序列圖4.2 操作流程詳解 5. UDP網絡管理配置模型 …

AI搜索引擎下的內容優化新范式:GEO的關鍵技術解析

摘要&#xff1a; 生成式AI搜索引擎的崛起&#xff0c;催生了GEO&#xff08;Generative Engine Optimization&#xff09;這一新的優化領域。本文將深入剖析GEO背后的關鍵技術&#xff0c;包括深度語義理解、結構化內容生成、以及AI算法的適配性&#xff0c;旨在為品牌在AI時代…

Java Lambda表達式是什么,怎么用

這種代碼是什么&#xff0c;怎么閱讀/*** 批量插入** param entityList ignore* param batchSize ignore* return ignore*/Transactional(rollbackFor Exception.class)Overridepublic boolean saveBatch(Collection<T> entityList, int batchSize) {String sqlStateme…

集成運算放大器(反向加法,減法)

反向加法電路原理&#xff1a;示波器顯示&#xff1a;結論&#xff1a;輸出電壓-&#xff08;R4/R1*V1R4/R2*V2R4/R3*V3&#xff09;。平衡電阻R4等于R1和R2和R3的并聯電壓。減法運算電路原理&#xff1a;結論&#xff1a;減法運算電路分為三種不同情況&#xff0c;第一種情況為…

Maven入門到精通

目錄 一&#xff0c;Maven概述 1.1介紹 1.2安裝 1.3Maven生命周期和插件 1.4Maven的坐標的本地倉庫的存儲地址 二&#xff0c;依賴管理 2.1依賴管理——依賴范圍 2.2依賴管理——添加依賴 獲取依賴坐標 依賴添加后的操作 2.3依賴管理——依賴傳遞 2.4依賴管理——依…

計算機網絡 TCP 延遲確認機制

TCP 延遲確認&#xff08;Delayed Acknowledgments&#xff0c;簡稱 Delayed ACK&#xff09;是 TCP 協議中一項旨在減少網絡中小數據包數量、提升傳輸效率的優化機制。其核心思想是&#xff1a;不立即回復 ACK&#xff0c;而是等待一段時間&#xff08;通常 40ms&#xff09;&…

【visual studio】visual studio配置環境opencv和onnxruntime

下載opencv https://opencv.org/releases/?spma2ty_o01.29997173.0.0.57f4c921RELipW配置環境變量visual studio配置opencv 新建c項目選中文件后右鍵選擇屬性添加include文件夾庫文件添加lib添加lib文件 將上一步的lib文件夾下的兩個文件復制到這里以下兩者區別在于&#xff0…

【Java】多線程Thread類

1. 進程與線程進程與線程的基本認識進程&#xff08;Process&#xff09;&#xff1a;進程是程序的一次動態執行過程&#xff0c;它經歷了從代碼加載、執行、到執行完畢的一個完整過程&#xff1b;同時也是并發執行的程序在執行過程中分配和管理資源的基本單位&#xff0c;競爭…

C/C++復習(四)

一.模版 模版涉及的是泛型編程&#xff0c;即通過編譯器去確定類型的編程方式&#xff0c;模版分為&#xff1a;類模板和函數模版&#xff0c;下面我們一一復習&#xff1a; 函數模版&#xff1a; 格式&#xff1a; template<typename T1, typename T2,......,typename Tn&g…

022 基礎 IO —— 文件

&#x1f984; 個人主頁: 小米里的大麥-CSDN博客 &#x1f38f; 所屬專欄: Linux_小米里的大麥的博客-CSDN博客 &#x1f381; GitHub主頁: 小米里的大麥的 GitHub ?? 操作環境: Visual Studio 2022 文章目錄基礎 IO —— C 語言文件 I/O 操作基礎前言1. C 語言文件操作函數匯…

MNN LLM Chat iOS 流式輸出優化實踐

本文介紹了在 iOS 平臺上使用 MNN 框架部署大語言模型&#xff08;LLM&#xff09;時&#xff0c;針對聊天應用中文字流式輸出卡頓問題的優化實踐。通過分析模型輸出與 UI 更新不匹配、頻繁刷新導致性能瓶頸以及缺乏視覺動畫等問題&#xff0c;作者提出了一套包含智能流緩沖、U…

【開發技巧】VS2022+QT5+OpenCV4.10開發環境搭建QT Creator

VS2022編譯器支持配置 QT5默認安裝以后支持的是VS2015與VS2017&#xff0c;不支持VS2022&#xff0c;所以必須首先在Qt Creator中配置支持VS2022。配置順序如下&#xff1a; 首先打開【工具】->【選項】 然點擊Kits里面的【編譯器】選項。點擊Manual下面的【C】然后點擊【…

【Linux系統】動靜態庫的制作

前言&#xff1a; 上文我們講到了文件系統【Linux系統】詳解Ext2&#xff0c;文件系統-CSDN博客 本文我們來講講動靜態庫的制作 庫 【Linux】編譯器gcc/g及其庫的詳細介紹_linux gcc 有哪些庫-CSDN博客 這篇文章的第4大點&#xff0c;簡單是介紹了一下庫的基本概念。 靜態庫 靜…

鏈式二叉樹的基本操作——遍歷

本文筆者將帶領讀者一起學習鏈式二叉樹的一些基本語法&#xff0c;至于更難一些的插入刪除等&#xff0c;筆者將在后續C更新后再次詳細帶領大家學習。 首先&#xff0c;在進行二叉樹之前&#xff0c;我們需要一顆二叉樹&#xff0c;而二叉樹的初始化現階段實現不太現實&#x…

Windows運維之以一種訪問權限不允許的方式做了一個訪問套接字的嘗試

一、問題場景 在Windows 上運維服務過程中&#xff0c;經常會遇到運行服務&#xff0c;部署安裝時候無任何問題&#xff0c;后續再某個特殊時間點&#xff0c;突然服務無法啟動了。再次啟動時&#xff0c;提示端口占用與以一種訪問權限不允許的方式做了一個訪問套接字的嘗試。 …