maven optional=true,SpringBoot @Conditional的使用

 2023-12-12 阅读 28 评论 0

摘要:結構說明 hello-spring-boot-starter: 沒什么用,引用了autoconfigure模塊 hello-spring-boot-starter-autoconfigure: 主要的自定義的starter模塊 hello-spring-boot-web-demo: web模塊 詳情可以看:入門SpringBoot自定義starter 1、@Conditional注解的說明

結構說明
在這里插入圖片描述

hello-spring-boot-starter: 沒什么用,引用了autoconfigure模塊
hello-spring-boot-starter-autoconfigure: 主要的自定義的starter模塊
hello-spring-boot-web-demo: web模塊
詳情可以看:入門SpringBoot自定義starter

1、@Conditional注解的說明

@Conditional是Spring4.0出現的新特性,他可以選擇性的創建Bean。

判斷是否滿足當前條件,如果滿足則創建Bean,不滿足則不創建

maven optional=true?

2、思路

根據說明可以了解到,@Conditional的作用是判斷是否滿足當前條件,如果滿足則創建Bean,不滿足則不創建

我們的思路是看看web模塊是否能夠注入starter提供的Bean
1、如果條件滿足則成功創建,通過接口能成功拿到返回值
2、如果條件滿足則成功創建,通過接口不能拿到返回值

2、autoconfigure模塊

根據上次的自定義starter直接創建一個Bean

3、@Conditional的使用

3.1、SpringBoot是如何實現這個功能的

這是DispatcherServlet的自動注冊配置類:
@Conditional接口是說如果DispatcherServletRegistrationCondition滿足條件才會去配置
在這里插入圖片描述

import在java中的用法?看下它的繼承關系圖:
頂層也是一個Condition的接口,然后SpringBoot自己去封裝了Condition的模塊方法。
你不信可以去看看其他的,比如Redis的相關配置,也會發現都是繼承SpringBootCondition。
在這里插入圖片描述

所以我們可以得出結論:
1、實現Condition接口并重寫matches方法
2、繼承SpringBootCondition抽象類并重寫getMatchOutcome方法

3.2、造輪子

跟著SpringBoot的思路,我們去實現第一種:實現Condition接口并重寫matches方法。
如果返回值為true則@Conditional則認為符合條件

Condition的編寫

public class WindowCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// todo 拿配置文件的信息return true;}
}

Service的編寫

public interface CmdService {String print(String cmd);
}
public class WindowCmdService implements CmdService {@Overridepublic String print(String cmd) {return "window cmd ...";}
}

自動配置類

public class CmdServiceConditionAutoConfiguration {/*** 當WindowCondition方法中的matches返回true的時候,* WindowCmdService會被注入,否則不注入。*/@Bean@Conditional(WindowCondition.class)public WindowCmdService windowComService(){return new WindowCmdService();}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.mecuros.springboot.custom.starter.CmdServiceConditionAutoConfiguration

Spring Boot陳恒、

4、驗證

在web模塊引入starter并寫出Controller接口

@RestController("/conditional")
public class ConditionalController {@Resourceprivate WindowCmdService windowCmdService;@GetMapping("/window/{cmd}")public String window(@PathVariable String cmd){return windowCmdService.print(cmd);}
}

4.1、不用@Conditional的情況

不用@Conditional注解默認會創建WindowService
image.png

4.2、用@Conditional的情況

4.2.1、WindowConditional為true時

一切正常
image.png

4.2.2、WindowConditional為false時

SpringBootVFS?image.png
image.png

5、總結

我們發現:
當Conditional為false,SpringBoot會報錯。
當Conditional為true,接口正常。


證明:@Conditional注解需要配合兩種方法使用
1、實現Condition接口并重寫matches方法
2、繼承SpringBootCondition抽象類并重寫getMatchOutcome方法
并且在自動配置那里配合@Bean來一起使用。

6、其他知識點(待驗證,后面會繼續驗證)

@Conditional擴展注解 作用(判斷是否滿足當前指定條件)
@ConditionalOnJava 系統的java版本是否符合要求
@ConditionalOnBean 容器中存在指定Bean;
@ConditionalOnMissingBean 容器中不存在指定Bean;
@ConditionalOnExpression 滿足SpEL表達式指定
@ConditionalOnClass 系統中有指定的類
@ConditionalOnMissingClass 系統中沒有指定的類
@ConditionalOnSingleCandidate 容器中只有一個指定的Bean,或者這個Bean是首選Bean
@ConditionalOnProperty 系統中指定的屬性是否有指定的值
@ConditionalOnResource 類路徑下是否存在指定資源文件
@ConditionalOnWebApplication 當前是web環境
@ConditionalOnNotWebApplication 當前不是web環境
@ConditionalOnJndi JNDI存在指定項

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/196293.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息