SpringBoot中@ConditionalOnBean注解的具體使用
1. 前言
在 Spring Boot 中,條件注解(Conditional 注解) 是一種強大的功能,允許我們根據(jù)某些條件動態(tài)地注冊或跳過特定的 Bean。其中,@ConditionalOnBean 是最常用的條件注解之一,它的作用是:當 Spring 容器中存在指定的 Bean 時,當前 Bean 才會被注冊。
本篇文章將詳細介紹 @ConditionalOnBean 的使用場景、原理,并提供多個示例幫助理解。
2. @ConditionalOnBean 作用與基本用法
2.1 @ConditionalOnBean 的作用
@ConditionalOnBean 主要用于以下場景:
- 按需加載 Bean:只有在某個 Bean 存在時,另一個 Bean 才會被創(chuàng)建。
- 模塊化設計:某些功能模塊需要依賴特定 Bean 才能啟用,例如 僅當某個組件存在時,自動配置才會生效。
- 避免 Bean 沖突:如果某個 Bean 依賴其他 Bean,則可使用
@ConditionalOnBean確保它不會因缺少依賴而加載失敗。
2.2 基本用法
示例:當 DataSource Bean 存在時,才創(chuàng)建 MyService Bean
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 實例,實際可用 HikariDataSource、Druid 等
return new FakeDataSource();
}
@Bean
@ConditionalOnBean(DataSource.class) // 僅當 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í)行結果:
MyService 被創(chuàng)建
如果 dataSource() 方法被注釋掉,則 MyService 不會被創(chuàng)建。
3. @ConditionalOnBean 詳解
@ConditionalOnBean 提供了多個屬性,可以更加靈活地控制 Bean 的創(chuàng)建。
3.1 value 和 type 屬性(指定 Bean 類型)
用于指定某種類型的 Bean 存在時,當前 Bean 才會被注冊。
@Bean
@ConditionalOnBean(value = DataSource.class) // 僅當 DataSource 存在時生效
public MyRepository myRepository() {
return new MyRepository();
}
等效于:
@Bean
@ConditionalOnBean(type = "javax.sql.DataSource") // 使用全限定類名
public MyRepository myRepository() {
return new MyRepository();
}
區(qū)別:
value:直接使用 Class 類型,編譯時檢查更安全。type:使用字符串,可用于避免某些類找不到(如可選依賴)。
3.2 name 屬性(指定 Bean 名稱)
用于 指定某個 Bean 名稱是否存在 來決定當前 Bean 是否加載。
@Bean
@ConditionalOnBean(name = "customBean") // 僅當名為 customBean 的 Bean 存在時注冊
public MyComponent myComponent() {
return new MyComponent();
}
3.3 annotation 屬性(指定 Bean 需要標注的注解)
可以指定某些 Bean 是否包含特定注解,如果包含,則當前 Bean 才會被注冊。
@Bean
@ConditionalOnBean(annotation = Repository.class) // 僅當存在 @Repository 注解的 Bean 時生效
public MyService myService() {
return new MyService();
}
3.4 search 屬性(搜索范圍)
默認情況下,@ConditionalOnBean 只會在 當前應用上下文 中查找 Bean,而不會查找 父上下文(即 Spring Boot 的 ApplicationContext 層級)。
search 選項可以指定搜索范圍:
ALL:在所有父子ApplicationContext中搜索。CURRENT(默認):僅搜索當前ApplicationContext。
@Bean
@ConditionalOnBean(value = DataSource.class, search = SearchStrategy.ALL) // 在所有上下文中搜索
public MyService myService() {
return new MyService();
}
4. @ConditionalOnBean 使用場景
場景 1:按需加載數(shù)據(jù)庫相關 Bean
如果應用程序中 使用了數(shù)據(jù)庫,則提供一個 DatabaseService,否則不創(chuàng)建:
@Bean
@ConditionalOnBean(DataSource.class)
public DatabaseService databaseService() {
return new DatabaseService();
}
場景 2:啟用某些自動配置
Spring Boot 的 spring-boot-autoconfigure 模塊大量使用 @ConditionalOnBean 來控制自動配置。例如:
- 只有當
DispatcherServlet存在時,Spring MVC 相關的自動配置才會生效。
@Configuration
@ConditionalOnBean(DispatcherServlet.class)
public class MvcAutoConfiguration {
// 僅當 DispatcherServlet 存在時,Spring MVC 配置生效
}
場景 3:可選依賴的組件
有時,某些功能是可選的,比如當 Redis 組件存在時,才創(chuàng)建緩存管理器:
@Bean
@ConditionalOnBean(name = "redisTemplate") // 只有當 redisTemplate 存在時才加載
public CacheManager cacheManager() {
return new RedisCacheManager();
}
5. @ConditionalOnBean vs @ConditionalOnMissingBean
| 注解 | 作用 |
|---|---|
@ConditionalOnBean | 當指定 Bean 存在時,才注冊當前 Bean |
@ConditionalOnMissingBean | 當指定 Bean 不存在時,才注冊當前 Bean |
示例:
@Bean
@ConditionalOnMissingBean(DataSource.class) // 僅當 DataSource 不存在時才創(chuàng)建
public DataSource defaultDataSource() {
return new DefaultDataSource();
}
6. 結論
在 Spring Boot 中,@ConditionalOnBean 可以幫助我們根據(jù) 是否存在特定 Bean 來 動態(tài)注冊 Bean,廣泛用于 按需加載、自動配置 等場景。
總結:
? 指定 Bean 類型:@ConditionalOnBean(DataSource.class)
? 指定 Bean 名稱:@ConditionalOnBean(name = "customBean")
? 指定 Bean 注解:@ConditionalOnBean(annotation = Repository.class)
? 搜索范圍:@ConditionalOnBean(search = SearchStrategy.ALL)
到此這篇關于SpringBoot中@ConditionalOnBean注解的具體使用的文章就介紹到這了,更多相關SpringBoot @ConditionalOnBean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring BeanFactory和FactoryBean有哪些區(qū)別
這篇文章主要介紹了Spring BeanFactory 與 FactoryBean 的區(qū)別詳情,BeanFactory 和 FactoryBean 的區(qū)別卻是一個很重要的知識點,在本文中將結合源碼進行分析講解,需要的小伙伴可以參考一下2023-02-02
SpringLDAP目錄服務之LdapTemplate與LDAP操作方式
本文將深入探討Spring LDAP的核心概念、LdapTemplate的使用方法以及如何執(zhí)行常見的LDAP操作,幫助開發(fā)者有效地將LDAP集成到Spring應用中,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-04-04
詳解java爬蟲jsoup解析多空格class數(shù)據(jù)
在本篇內(nèi)容中小編給大家分享了java爬蟲jsoup怎么解析多空格class數(shù)據(jù)的方法和技巧,需要的朋友們跟著學習下。2018-12-12
java 輸入3個數(shù)a,b,c,按大小順序輸出的實例講解
今天小編就為大家分享一篇java 輸入3個數(shù)a,b,c,按大小順序輸出的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07
Java中字符數(shù)組和字符串與StringBuilder和字符串轉換的講解
今天小編就為大家分享一篇關于Java中字符數(shù)組和字符串與StringBuilder和字符串轉換的講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03
Mybatis注解方式完成輸入?yún)?shù)為list的SQL語句拼接方式
這篇文章主要介紹了Mybatis注解方式完成輸入?yún)?shù)為list的SQL語句拼接方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11

