【Spring】Spring中8種常見依賴注入使用示例

在 Spring 中,IoC 注入可以通過多種方式實現,涵蓋不同場景的依賴管理。以下是 8 種常見場景的詳細示例及說明,結合 XML、注解和 Java 配置類三種方式。


1. 構造器注入(推薦方式)

通過構造器傳遞依賴,確保對象不可變且依賴完整。

注解方式:
@Service
public class OrderService {private final PaymentService paymentService;@Autowired // Spring 4.3+ 可省略(單構造器時)public OrderService(PaymentService paymentService) {this.paymentService = paymentService;}
}@Component
public class PaymentService {public void process() {System.out.println("Processing payment...");}
}
XML 方式:
<bean id="paymentService" class="com.example.PaymentService"/><bean id="orderService" class="com.example.OrderService"><constructor-arg ref="paymentService"/>
</bean>
Java 配置類:
@Configuration
public class AppConfig {@Beanpublic PaymentService paymentService() {return new PaymentService();}@Beanpublic OrderService orderService() {return new OrderService(paymentService());}
}

2. Setter 注入

通過 Setter 方法注入依賴,適合可選依賴或需要動態變更的場景。

注解方式:
@Service
public class ProductService {private InventoryService inventoryService;@Autowiredpublic void setInventoryService(InventoryService inventoryService) {this.inventoryService = inventoryService;}
}@Component
public class InventoryService {public void checkStock() {System.out.println("Checking stock...");}
}
XML 方式:
<bean id="inventoryService" class="com.example.InventoryService"/><bean id="productService" class="com.example.ProductService"><property name="inventoryService" ref="inventoryService"/>
</bean>

3. 字段注入(不推薦,但常見)

直接通過字段注入依賴,簡潔但隱藏依賴關系。

@Service
public class CartService {@Autowiredprivate DiscountService discountService;
}@Component
public class DiscountService {public void applyDiscount() {System.out.println("Applying discount...");}
}

4. 集合注入(多個同類型 Bean)

注入多個相同接口/父類的實現類。

示例代碼:
public interface NotificationSender {void send(String message);
}@Component
public class EmailSender implements NotificationSender {@Overridepublic void send(String message) {System.out.println("Email: " + message);}
}@Component
public class SmsSender implements NotificationSender {@Overridepublic void send(String message) {System.out.println("SMS: " + message);}
}
注入方式:
@Service
public class NotificationService {private final List<NotificationSender> senders;@Autowiredpublic NotificationService(List<NotificationSender> senders) {this.senders = senders;}public void broadcast(String message) {senders.forEach(sender -> sender.send(message));}
}

5. 條件注入(@Qualifier 或 @Primary)

解決多個同類型 Bean 的歧義性問題。

使用 @Qualifier
public interface DataSource {void connect();
}@Component("mysqlDataSource")
public class MySqlDataSource implements DataSource {@Overridepublic void connect() {System.out.println("MySQL connected");}
}@Component("oracleDataSource")
public class OracleDataSource implements DataSource {@Overridepublic void connect() {System.out.println("Oracle connected");}
}@Service
public class ReportService {private final DataSource dataSource;@Autowiredpublic ReportService(@Qualifier("mysqlDataSource") DataSource dataSource) {this.dataSource = dataSource;}
}
使用 @Primary
@Configuration
public class AppConfig {@Bean@Primary // 默認優先選擇public DataSource mysqlDataSource() {return new MySqlDataSource();}@Beanpublic DataSource oracleDataSource() {return new OracleDataSource();}
}

6. 外部化配置注入(@Value)

注入配置文件(如 application.properties)中的值。

配置文件:
app.name=MySpringApp
app.max.connections=10
注入方式:
@Component
public class AppConfigBean {@Value("${app.name}")private String appName;@Value("${app.max.connections}")private int maxConnections;// Getter/Setter
}

7. 循環依賴處理

構造器注入無法解決循環依賴,需改用 Setter 注入。

示例代碼:
@Service
public class ServiceA {private ServiceB serviceB;@Autowiredpublic void setServiceB(ServiceB serviceB) {this.serviceB = serviceB;}
}@Service
public class ServiceB {private ServiceA serviceA;@Autowiredpublic void setServiceA(ServiceA serviceA) {this.serviceA = serviceA;}
}

8. 條件化 Bean 注入(@Profile 或 @Conditional)

根據環境或條件動態選擇 Bean。

使用 @Profile
@Configuration
public class DataSourceConfig {@Bean@Profile("dev")public DataSource devDataSource() {return new H2DataSource();}@Bean@Profile("prod")public DataSource prodDataSource() {return new MySqlDataSource();}
}
使用 @Conditional
public class MongoDBCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return "true".equals(context.getEnvironment().getProperty("enable.mongo"));}
}@Configuration
public class DatabaseConfig {@Bean@Conditional(MongoDBCondition.class)public DataSource mongoDataSource() {return new MongoDataSource();}
}

總結

  • 構造器注入:推薦用于強制依賴,確保對象不可變。
  • Setter/字段注入:適合可選依賴或需要靈活性的場景。
  • 集合注入:處理多實現類的統一管理。
  • 條件注入:通過 @Qualifier@Primary@Profile 解決歧義。
  • 循環依賴:優先通過設計避免,或改用 Setter 注入。
  • 外部化配置:結合 @Value 動態注入屬性值。
  • 條件化 Bean:根據環境或業務規則動態裝配。

具體選擇取決于項目需求,Spring Boot 進一步簡化了配置(如自動配置、@ConditionalOnProperty)。

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

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

相關文章

藍橋杯 擺動序列

擺動序列 原題目鏈接 題目描述 如果一個序列的奇數項都比前一項大&#xff0c;偶數項都比前一項小&#xff0c;則稱為一個擺動序列。 即對于任意整數 i&#xff08;i ≥ 1&#xff09;滿足&#xff1a; a?? < a????&#xff0c;a???? > a?? 小明想知道&…

REINFORCE蒙特卡羅策略梯度算法詳解:python從零實現

&#x1f9e0; 向所有學習者致敬&#xff01; “學習不是裝滿一桶水&#xff0c;而是點燃一把火。” —— 葉芝 我的博客主頁&#xff1a; https://lizheng.blog.csdn.net &#x1f310; 歡迎點擊加入AI人工智能社區&#xff01; &#x1f680; 讓我們一起努力&#xff0c;共創…

深入了解Linux系統—— 操作系統

一、馮諾依曼體系結構 現在我們常見的計算機&#xff08;筆記本電腦等&#xff09;和不常見的計算機&#xff08;服務器&#xff09;它們都滿足馮諾依曼體系。 我們可以把計算機理解成一個個硬件組成的 輸入設備&#xff1a;鍵盤、鼠標、攝像頭、網卡、磁盤等輸出設備&#xf…

RPG7.準備GAS的工作

1.啟動項目&#xff0c;為項目添加gameplayability插件 2.添加abilitysystemcomponent的c類 3.添加attributeset的c類 4.往build.cs內添加模塊 5.進入CharacterBase內&#xff0c;添加gameplayasystem和attributbeset&#xff0c;覆寫PossessedBy()和GetAbilitysystemcomponent…

使用gitea發布軟件包

1、新建hello工程 &#xff08;1&#xff09;HelloApplication.java package cn.ac.trimps.sv;import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplicati…

從請求到響應:初探spring web

引入&#xff1a; 首先小編想分享下一些開發小知識 2000年——手寫servlet/JSP時代 在這個階段中&#xff0c;那時候寫后端代碼&#xff0c;可謂是個麻煩事。 畢竟什么都要自己干 發來的請求都要寫extends HttpServlet的類&#xff0c;手動在web.xml配置 <servlet>…

Redis從入門到實戰實戰篇2

面試重點&#xff1a;本篇包含悲觀鎖&#xff0c;樂觀鎖&#xff0c;多線程以及分布式鎖的知識 目錄 3.優惠卷秒殺 3.1 -全局唯一ID 3.2 -Redis實現全局唯一Id 3.3 添加優惠卷 3.4 實現秒殺下單 3.5 庫存超賣問題分析 3.6 樂觀鎖解決超賣問題 3.7 優惠券秒殺-一人一單 …

LabVIEW實驗室項目中使用類模塊與仿真

在 LabVIEW 程序開發過程中&#xff0c;借鑒面向對象的類思想進行模塊化架構設計&#xff0c;并結合仿真功能&#xff0c;能夠高效應對不同場景的開發需求。 ? 以實驗室場景為例&#xff0c;LabVIEW 開發常面臨設備種類繁多、調試周期漫長&#xff0c;且硬件難以一次性到位的情…

ES6入門---第二單元 模塊三:對象新增、

一&#xff1a;對象簡潔語法&#xff1a; 1、變量簡潔 <script>let name Strive;let age 18;let json {name, //name:name,age //age:age};console.log(json);</script> 2、函數簡潔 let json {name, //name:name,age, //age:age/* showA:functi…

Python創意:AI圖像生成——用代碼繪制未來藝術

當代碼邂逅藝術:AI圖像生成的革命 在數字藝術領域,一場由Python和AI技術引領的革命正在悄然發生。無需專業繪畫技巧,僅憑幾行代碼,普通人也能創造出令人驚嘆的藝術作品。AI圖像生成技術打破了藝術創作的門檻,讓想象力成為唯一的限制。 核心技術方案 1. 技術架構 我們采…

一、Shell 腳本基礎

一、Shell 簡介 1.Shell 的定義與作用 Shell&#xff0c;通常被稱為命令行解釋器 (Command Line Interpreter)&#xff0c;是用戶 &#x1f464; 與 Linux/Unix 操作系統內核進行交互 ?? 的“橋梁” &#x1f309;。它扮演著翻譯官 &#x1f5e3;? 的角色&#xff1a; 接…

青少年編程與數學 02-018 C++數據結構與算法 21課題、機器學習與人工智能算法

青少年編程與數學 02-018 C數據結構與算法 21課題、機器學習與人工智能算法 一、線性回歸算法二、邏輯回歸算法三、K近鄰算法&#xff08;K-Nearest Neighbors, KNN&#xff09;四、決策樹算法五、支持向量機&#xff08;SVM&#xff09;六、神經網絡算法七、聚類算法八、降維算…

【數據結構】——單鏈表練習(1)

一、移除鏈表元素 題目鏈接&#xff1a; 移除鏈表元素 那么根據題目的要求我們大致明白這道題要做什么&#xff0c;就是將一個鏈表中&#xff0c;和指定的值相等的元素的節點刪除&#xff0c;然后返回刪除后的新的鏈表&#xff0c;然后題目給我們傳入的參數是鏈表的頭節點和指…

AI大模型基礎設施:主流的幾款開源AI大語言模型的本地部署成本

以下是對目前主流開源AI大語言模型&#xff08;如DeepSeek R1、LLaMA系列、Qwen等&#xff09;本地部署成本的詳細分析&#xff0c;涵蓋計算機硬件、顯卡等成本&#xff0c;價格以美元計算。成本估算基于模型參數規模、硬件需求&#xff08;GPU、CPU、RAM、存儲等&#xff09;以…

AI生成視頻檢測方法及其相關研究

目錄標題 【1】AI-Generated Video Detection via Spatio-Temporal Anomaly Learning【2】DeCoF: Generated Video Detection via Frame Consistency【2.1】Spatiotemporal Convolutional Neural Networks (STCNN) rely on spatial artifacts【2.2】Capturing Universal Spatia…

仿騰訊會議——服務器注釋

目錄 1、修改協議 2、修改登錄請求結構體 3、修改登錄回復結構體 4、修改注冊請求結構體 5、修改發送登錄請求函數 6、實現發送注冊請求函數 7、修改mysql存儲數據格式 8、自己完成部分 1、修改協議 2、修改登錄請求結構體 3、修改登錄回復結構體 4、修改注冊請求結構體…

list的迭代器詳講

1.list的迭代器就是封裝了節點指針的類 2.迭代器失效 迭代器失效即迭代器封裝的節點指針無效 。因為 list 的底層結構為帶頭結點的雙向循環鏈表 &#xff0c;因此 在 list 中進行插入時是不會導致 list 的迭代 器失效的&#xff0c;只有在刪除時才會失效&#xff0c;并且失效的…

deepSeek論文寫作提示詞指令大全(覆蓋選題、寫作、潤色到投稿全流程)

一、選題與框架設計 1、跨學科選題突破 指令:"結合[領域A]與[領域B]的前沿理論,生成5個交叉創新性論文選題,要求每個選題包含可行性評估。"(支持跨學科研究創新) 示例:"在人工智能與教育心理學領域生成選題,分析理論適用性與資源獲取難度。" 2、…

win11安裝WSL(創建用戶、更改或重置密碼)

文章目錄 win11安裝WSL設置 Linux 用戶名和密碼更改或重置密碼更新和升級軟件包WSL 命令互操作性WSL 的基本命令安裝列出可用的 Linux 發行版列出已安裝的 Linux 發行版將 WSL 版本設置為 1 或 2設置默認 WSL 版本設置默認 Linux 發行版將目錄更改為主頁通過 PowerShell 或 CMD…

Vue.js 與 Ajax (vue-resource) 的深入解析

Vue.js 與 Ajax (vue-resource) 的深入解析 引言 在Web開發中,前后端的交互是不可或缺的。Ajax(異步JavaScript和XML)技術允許我們在不重新加載整個頁面的情況下,與服務器交換數據和更新部分網頁內容。Vue.js 作為一種流行的前端框架,提供了多種方式來處理Ajax請求。其中…