SpringBoot原始碼@ConditionalOnBean與@ConditionalOnClass你清楚嗎
@ConditionalOnBean // 當給定的在bean存在時,則例項化當前Bean
@ConditionalOnMissingBean // 當給定的在bean不存在時,則例項化當前Bean
@ConditionalOnClass // 當給定的類名在類路徑上存在,則例項化當前Bean
@ConditionalOnMissingClass // 當給定的類名在類路徑上不存在,則例項化當前Bean
下面我通過案例深入講下@ConditionalOnBean 註解,這個理解其它也就理解了。
一、@ConditionalOnBean概念
需求場景 比如下面一種場景,我在例項化People物件的時候,需要注入一個City物件。這個時候問題來了,如果city沒有例項化,那麼下面就會報空指標或者直接報錯。
所以這裡需求很簡單,就是當前city存在則例項化people,如果不存在則不例項化people,這個時候@ConditionalOnBean 的作用來了。
@Bean
public People people(City city) {
//這裡如果city實體沒有成功注入 這裡就會報空指標
city.setCityName("千島湖");
city.setCityCode(301701);
return new People("小小", 3, city);
}
1、@ConditionalOnBean註解定義
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class)
public @interface ConditionalOnBean {
/**
* 需要作為條件的類的Class物件陣列
*/
Class<?>[] value() default {};
/**
* 需要作為條件的類的Name,Class.getName()
*/
String[] type() default {};
/**
* (用指定註解修飾的bean)條件所需的註解類
*/
Class<? extends Annotation>[] annotation() default {};
/**
* spring容器中bean的名字
*/
String[] name() default {};
/**
* 搜尋容器層級,當前容器,父容器
*/
SearchStrategy search() default SearchStrategy.ALL;
/**
* 可能在其泛型引數中包含指定bean型別的其他類
*/
Class<?>[] parameterizedContainer() default {};
}
下面舉例說明。
二、@ConditionalOnBean示例
1、Bean實體
1)City類
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class City {
/**
* 城市名稱
*/
private String cityName;
/**
* 城市code
*/
private Integer cityCode;
}
2)People類
這裡City作為People一個屬性欄位。
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class People {
/**
* 姓名
*/
private String name;
/**
* 年齡
*/
private Integer age;
/**
* 城市資訊
*/
private City city;
}
2、Config類
這裡寫個正常的配置類,City成功注入到IOC容器中。
@Slf4j
@Configuration
public class Config {
@Bean
public City city() {
City city = new City();
city.setCityName("千島湖");
return city;
}
@Bean
public People people(City city) {
//這裡如果city實體沒有成功注入 這裡就會報空指標
city.setCityCode(301701);
return new People("小小", 3, city);
}
}
3、Test測試類
@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
public class TestConditionOn {
@Autowired(required=false)
private People people;
@Test
public void test() {
System.out.println("= = = = = = = = = = = = = ");
System.out.println("people = " + people);
System.out.println("= = = = = = = = = = = = = ");
}
}
執行結果
一切正常,這個很符合我們實際開發中的需求。但是如果有一種情況,就是我的city並沒有被注入。我把上面這部分注視掉。
// @Bean
// public City city() {
// City city = new City();
// city.setCityName("千島湖");
// return city;
// }
再執行測試類
發現啟動直接報錯了,這當然不是我們希望看到的,我們是要當city已經注入那麼例項化people,如果沒有注入那麼不例項化people。
@Slf4j
@Configuration
public class Config {
// @Bean
// public City city() {
// City city = new City();
// city.setCityName("千島湖");
// return city;
// }
/**
* 這裡加了ConditionalOnBean註解,就代表如果city存在才例項化people
*/
@Bean
@ConditionalOnBean(name = "city")
public People people(City city) {
//這裡如果city實體沒有成功注入 這裡就會報空指標
city.setCityCode(301701);
return new People("小小", 3, city);
}
}
再執行測試類
很明顯,上面因為city已經註釋調,所以也導致無法例項化people,所以people為null。
注意有點要注意的,就是一旦使用@Autowired那就預設代表當前Bean一定是已經存在的,如果為null,會報錯。所以這裡要修改下。
@Autowired(required=false) //required=false 的意思就是允許當前的Bean物件為null。
總結講了這個註解,其它三個註解的意思大致差不多,在實際開發過程中可以根據實際情況使用該註解。
相關文章
- SpringBoot(16)—@ConditionalOnBean與@ConditionalOnClassSpring BootBean
- SpringBoot @ConditionalOnBean、@ConditionalOnMissingBean註解原始碼分析與示例Spring BootBean原始碼
- springboot的@ConditionalOnBean註解Spring BootBean
- 你真的清楚DateTime in C#嗎?C#
- 資料倉儲分層你清楚了嗎
- 【原始碼分析】- 在SpringBoot中你會使用REST風格處理請求嗎?原始碼Spring BootREST
- JavaScript基礎——你真的清楚JavaScript是什麼嗎?JavaScript
- 銀行資料庫選型需求,你真的清楚嗎?資料庫
- Java中的深淺拷貝問題,你清楚嗎?Java
- 你知道Golang原始碼各目錄的作用嗎?Golang原始碼
- 面試官:你分析過SpringMVC的原始碼嗎?面試SpringMVC原始碼
- 原始碼為你而開嗎??Is Open Source for You? (轉)原始碼
- Vue 3 原始碼開放,今天你學習了嗎?Vue原始碼
- 直播原始碼,一對一交友原始碼,短視訊原始碼,你知道他們的區別嗎?原始碼
- 關於學習Python的疑問,你都清楚了嗎?Python
- Flex屬性你真的搞清楚了嗎?我深表懷疑Flex
- jboss中的幾個配置檔案,你搞清楚了嗎?
- SpringBoot原始碼分析Spring Boot原始碼
- 混亂C原始碼的幾個錯誤,你犯了嗎?原始碼
- 這些 SpringBoot 面試題你會嗎?Spring Boot面試題
- 實現SpringBoot + Redis快取的原始碼與教程Spring BootRedis快取原始碼
- 你知道在springboot中如何使用WebSocket嗎Spring BootWeb
- 這幾個關於Spring 依賴注入的問題你清楚嗎?Spring依賴注入
- 阿里一面:Spring和SpringMvc父子容器你能說清楚嗎阿里SpringMVC
- 膜結構車棚安裝時的注意事項你清楚嗎JOQ
- 你會敲程式碼嗎
- SpringBoot 原始碼解析筆記Spring Boot原始碼筆記
- SpringBoot原始碼解析-Bean的載入與自動化配置Spring Boot原始碼Bean
- linux 記憶體管理 (一)這些問題,你都能解釋清楚嗎?Linux記憶體
- SpringBoot原始碼學習4——SpringBoot內嵌Tomcat啟動流程原始碼分析Spring Boot原始碼Tomcat
- 「Vue原始碼學習」你真的知道插槽Slot是怎麼“插”的嗎Vue原始碼
- Android原始碼解析Handler系列第(五)篇 ---HandlerThread你用過嗎?Android原始碼thread
- 你真的瞭解“密碼”嗎?密碼
- 你的密碼真的安全嗎?密碼
- 你會執行指令碼嗎指令碼
- 你需要每天寫程式碼嗎?
- 【白話科普】網站圖片不顯示,背後的原因你都清楚嗎網站
- 先是IPV6,再是WI-FI7你都清楚這是什麼嗎?