上一篇講的@Conditional
能夠經過條件控制是否注入Bean,這篇講下有關Bean其它幾個經常使用的註解使用方式java
@ConditionalOnBean // 當給定的在bean存在時,則實例化當前Bean @ConditionalOnMissingBean // 當給定的在bean不存在時,則實例化當前Bean @ConditionalOnClass // 當給定的類名在類路徑上存在,則實例化當前Bean @ConditionalOnMissingClass // 當給定的類名在類路徑上不存在,則實例化當前Bean
下面我經過案例深刻講下@ConditionalOnBean
註解,這個理解其它也就理解了。git
需求場景
好比下面一種場景,我在實例化People對象的時候,須要注入一個City對象。這個時候問題來了,若是city沒有實例化,那麼下面就會報空指針或者直接報錯。
因此這裏需求很簡單,就是當前city存在則實例化people,若是不存在則不實例化people,這個時候@ConditionalOnBean
的做用來了。github
@Bean public People people(City city) { //這裏若是city實體沒有成功注入 這裏就會報空指針 city.setCityName("千島湖"); city.setCityCode(301701); return new People("小小", 3, city); }
@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 {}; }
下面舉例說明。
spring
1)City類數組
@Data @ToString @AllArgsConstructor @NoArgsConstructor public class City { /** * 城市名稱 */ private String cityName; /** * 城市code */ private Integer cityCode; }
2)People類測試
這裏City做爲People一個屬性字段。ui
@Data @ToString @NoArgsConstructor @AllArgsConstructor public class People { /** * 姓名 */ private String name; /** * 年齡 */ private Integer age; /** * 城市信息 */ private City city; }
這裏寫個正常的配置類,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); } }
@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("= = = = = = = = = = = = = "); } }
運行結果code
一切正常,這個很符合咱們實際開發中的需求。可是若是有一種狀況,就是個人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。
總結
講了這個註解,其它三個註解的意思大體差很少,在實際開發過程當中能夠根據實際狀況使用該註解。
GitHub源碼
https://github.com/yudiandemingzi/SpringBootBlog
項目名稱 04-conditionalon
只要本身變優秀了,其餘的事情纔會跟着好起來(中將4)