SpringBoot中的@ConditionalOnBean注解用法解讀
1. 前言
在 Spring Boot 中,條件注解(Conditional 注解) 是一種強(qiáng)大的功能,允許我們根據(jù)某些條件動態(tài)地注冊或跳過特定的 Bean。其中,@ConditionalOnBean 是最常用的條件注解之一,它的作用是:當(dāng) Spring 容器中存在指定的 Bean 時,當(dāng)前 Bean 才會被注冊。
本篇文章將詳細(xì)介紹 @ConditionalOnBean 的使用場景、原理,并提供多個示例幫助理解。
2.@ConditionalOnBean作用與基本用法
2.1@ConditionalOnBean的作用
@ConditionalOnBean 主要用于以下場景:
- 按需加載 Bean:只有在某個 Bean 存在時,另一個 Bean 才會被創(chuàng)建。
- 模塊化設(shè)計:某些功能模塊需要依賴特定 Bean 才能啟用,例如 僅當(dāng)某個組件存在時,自動配置才會生效。
- 避免 Bean 沖突:如果某個 Bean 依賴其他 Bean,則可使用
@ConditionalOnBean確保它不會因缺少依賴而加載失敗。
2.2 基本用法
示例:當(dāng)DataSourceBean 存在時,才創(chuàng)建MyServiceBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class MyConfig {
@Bean
public DataSource dataSource() {
// 這里模擬 DataSource 實(shí)例,實(shí)際可用 HikariDataSource、Druid 等
return new FakeDataSource();
}
@Bean
@ConditionalOnBean(DataSource.class) // 僅當(dāng) DataSource 存在時,才創(chuàng)建 MyService
public MyService myService() {
return new MyService();
}
}
class MyService {
public MyService() {
System.out.println("MyService 被創(chuàng)建");
}
}
class FakeDataSource implements DataSource {
// 這里可以模擬 DataSource 方法
}
執(zhí)行結(jié)果:
MyService 被創(chuàng)建
如果 dataSource() 方法被注釋掉,則 MyService 不會被創(chuàng)建。
3.@ConditionalOnBean詳解
@ConditionalOnBean 提供了多個屬性,可以更加靈活地控制 Bean 的創(chuàng)建。
3.1value和type屬性(指定 Bean 類型)
用于指定某種類型的 Bean 存在時,當(dāng)前 Bean 才會被注冊。
@Bean
@ConditionalOnBean(value = DataSource.class) // 僅當(dāng) DataSource 存在時生效
public MyRepository myRepository() {
return new MyRepository();
}
等效于:
@Bean
@ConditionalOnBean(type = "javax.sql.DataSource") // 使用全限定類名
public MyRepository myRepository() {
return new MyRepository();
}
區(qū)別:
value:直接使用 Class 類型,編譯時檢查更安全。type:使用字符串,可用于避免某些類找不到(如可選依賴)。
3.2name屬性(指定 Bean 名稱)
用于 指定某個 Bean 名稱是否存在 來決定當(dāng)前 Bean 是否加載。
@Bean
@ConditionalOnBean(name = "customBean") // 僅當(dāng)名為 customBean 的 Bean 存在時注冊
public MyComponent myComponent() {
return new MyComponent();
}
3.3annotation屬性(指定 Bean 需要標(biāo)注的注解)
可以指定某些 Bean 是否包含特定注解,如果包含,則當(dāng)前 Bean 才會被注冊。
@Bean
@ConditionalOnBean(annotation = Repository.class) // 僅當(dāng)存在 @Repository 注解的 Bean 時生效
public MyService myService() {
return new MyService();
}
3.4search屬性(搜索范圍)
默認(rèn)情況下,@ConditionalOnBean 只會在 當(dāng)前應(yīng)用上下文 中查找 Bean,而不會查找 父上下文(即 Spring Boot 的 ApplicationContext 層級)。
search 選項(xiàng)可以指定搜索范圍:
ALL:在所有父子ApplicationContext中搜索。CURRENT(默認(rèn)):僅搜索當(dāng)前ApplicationContext。
@Bean
@ConditionalOnBean(value = DataSource.class, search = SearchStrategy.ALL) // 在所有上下文中搜索
public MyService myService() {
return new MyService();
}
4.@ConditionalOnBean使用場景
場景 1:按需加載數(shù)據(jù)庫相關(guān) Bean
如果應(yīng)用程序中 使用了數(shù)據(jù)庫,則提供一個 DatabaseService,否則不創(chuàng)建:
@Bean
@ConditionalOnBean(DataSource.class)
public DatabaseService databaseService() {
return new DatabaseService();
}
場景 2:啟用某些自動配置
Spring Boot 的 spring-boot-autoconfigure 模塊大量使用 @ConditionalOnBean 來控制自動配置。例如:
- 只有當(dāng)
DispatcherServlet存在時,Spring MVC 相關(guān)的自動配置才會生效。
@Configuration
@ConditionalOnBean(DispatcherServlet.class)
public class MvcAutoConfiguration {
// 僅當(dāng) DispatcherServlet 存在時,Spring MVC 配置生效
}
場景 3:可選依賴的組件
有時,某些功能是可選的,比如當(dāng) Redis 組件存在時,才創(chuàng)建緩存管理器:
@Bean
@ConditionalOnBean(name = "redisTemplate") // 只有當(dāng) redisTemplate 存在時才加載
public CacheManager cacheManager() {
return new RedisCacheManager();
}
5.@ConditionalOnBeanvs@ConditionalOnMissingBean
| 注解 | 作用 |
|---|---|
| @ConditionalOnBean | 當(dāng)指定 Bean 存在時,才注冊當(dāng)前 Bean |
| @ConditionalOnMissingBean | 當(dāng)指定 Bean 不存在時,才注冊當(dāng)前 Bean |
示例:
@Bean
@ConditionalOnMissingBean(DataSource.class) // 僅當(dāng) DataSource 不存在時才創(chuàng)建
public DataSource defaultDataSource() {
return new DefaultDataSource();
}
6. 結(jié)論
在 Spring Boot 中,@ConditionalOnBean 可以幫助我們根據(jù) 是否存在特定 Bean 來 動態(tài)注冊 Bean,廣泛用于 按需加載、自動配置 等場景。
小結(jié):
- 指定 Bean 類型:
@ConditionalOnBean(DataSource.class) - 指定 Bean 名稱:
@ConditionalOnBean(name = "customBean") - 指定 Bean 注解:
@ConditionalOnBean(annotation = Repository.class) - 搜索范圍:
@ConditionalOnBean(search = SearchStrategy.ALL)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
MyBatis源碼解析——獲取SqlSessionFactory方式
這篇文章主要介紹了MyBatis源碼解析——獲取SqlSessionFactory方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
Debian配置JDK1.7 與Linux Java Helloworld
這篇文章主要介紹了Debian配置JDK1.7 與Linux Java Helloworld 的相關(guān)資料,需要的朋友可以參考下2016-06-06
SpringBoot中@Value獲取值和@ConfigurationProperties獲取值用法及比較
在Spring Boot中,@Value注解是一個非常有用的特性,它允許我們將外部的配置注入到我們的Bean中,@ConfigurationProperties用于將配置文件中的屬性綁定到 Java Bean 上,本文介紹了@Value獲取值和@ConfigurationProperties獲取值用法及比較,需要的朋友可以參考下2024-08-08
Spring Boot 簡單使用EhCache緩存框架的方法
本篇文章主要介紹了Spring Boot 簡單使用EhCache緩存框架的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
基于hibernate實(shí)現(xiàn)的分頁技術(shù)實(shí)例分析
這篇文章主要介紹了基于hibernate實(shí)現(xiàn)的分頁技術(shù),結(jié)合實(shí)例形式分析了Hibernate分頁技術(shù)的原理,實(shí)現(xiàn)步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-03-03
SpringBoot整合WebSocket實(shí)現(xiàn)聊天室流程全解
WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。本文將通過SpringBoot集成WebSocket實(shí)現(xiàn)簡易聊天室,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,感興趣的可以了解一下2023-01-01
如何使用java給局域網(wǎng)的電腦發(fā)送開機(jī)數(shù)據(jù)包
這篇文章主要為大家詳細(xì)介紹了如何使用java給局域網(wǎng)的電腦發(fā)送開機(jī)數(shù)據(jù)包,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-09-09

