在 Spring 框架中,@Primary
注解用于解決依賴注入時的歧義性(Ambiguity)問題。當 Spring 容器中存在多個相同類型的 Bean 時,通過 @Primary
標記其中一個 Bean 作為默認的首選注入對象。
核心作用:
-
解決多個同類型 Bean 的沖突
當有多個實現同一接口或相同類型的 Bean 時,Spring 無法自動確定注入哪個 Bean,會拋出NoUniqueBeanDefinitionException
。使用@Primary
可指定默認注入的 Bean。 -
隱式選擇優先級
被標記為@Primary
的 Bean 會被優先注入,無需額外使用@Qualifier
指定名稱。
使用示例:
場景定義
假設有一個支付接口 PaymentService
和兩個實現類:
public interface PaymentService {void pay();
}@Component
public class CreditCardService implements PaymentService {@Overridepublic void pay() { System.out.println("信用卡支付"); }
}@Component
public class AlipayService implements PaymentService {@Overridepublic void pay() { System.out.println("支付寶支付"); }
}
問題:依賴注入歧義
若直接注入 PaymentService
,Spring 會報錯:
@Autowired
private PaymentService paymentService; // 拋出 NoUniqueBeanDefinitionException
解決方案:使用 @Primary
標記其中一個實現類為默認首選:
@Component
@Primary // 指定為默認注入的 Bean
public class AlipayService implements PaymentService { ... }
此時注入會成功選擇 AlipayService
:
@Autowired
private PaymentService paymentService; // 隱式注入 AlipayService
與其他注解的優先級:
-
@Primary
vs@Qualifier
@Qualifier
顯式指定 Bean 名稱的優先級高于@Primary
。- 例如:
@Autowired @Qualifier("creditCardService")
會覆蓋@Primary
。
-
多個
@Primary
的沖突
如果多個同類型 Bean 都被標記為@Primary
,Spring 會再次拋出歧義異常。
常見使用場景:
- 數據庫多數據源配置
在多個DataSource
Bean 中,標記默認使用的數據源。 - 不同環境下的實現類
例如在測試和生產環境中提供同一接口的不同實現,通過@Primary
切換默認實現。 - 第三方庫的擴展
當覆蓋第三方庫提供的 Bean 時,將自己的實現標記為@Primary
。
配置方式:
除了注解在類上,也可以在 @Bean
方法中使用:
@Configuration
public class AppConfig {@Bean@Primary // 標記此 Bean 為首選public PaymentService alipayService() {return new AlipayService();}
}
總結:
場景 | 解決方案 |
---|---|
多個同類型 Bean,需默認注入一個 | 在目標 Bean 添加 @Primary |
需要臨時覆蓋默認注入 | 配合 @Qualifier 指定名稱 |
關鍵點:@Primary
是 Spring 解決依賴注入歧義性的輕量級方案,通過隱式指定默認 Bean 簡化配置,但在需要精確控制的場景中仍需結合 @Qualifier
使用。