@Conditional注解可以說是SpringBoot的條件注解,表示組件只有在所有指定條件都匹配時才有資格注冊,條件是可以在 bean 定義注冊之前??以編程方式確定的任何狀態,@Conditional注解可以通過以下任何方式使用:
如果@Configuration類被標記為@Conditional ,那么與該類關聯的所有@Bean方法、 @Import 注解和@ComponentScan注解都將受制于條件。
SpringBoot提供的@ConditionalOn*的注解都是基于@Conditional注解實現
Spring Authorization Server?僅當滿足所有指定要求的 bean 已包含在BeanFactory中時才匹配的Conditional 。 必須滿足所有要求才能匹配條件,但不必由同一個 bean 滿足。
僅當指定的類在類路徑上時才匹配的Conditional 。
可以在@Configuration類上安全地指定value() ,因為在加載類之前使用 ASM 解析注釋元數據。 放置在@Bean方法上時需要格外小心,考慮將條件隔離在單獨的Configuration類中,特別是如果方法的返回類型與value()中的值匹配。
當指定的云平臺處于活動狀態時匹配的Conditional。?
取決于 SpEL 表達式的值的條件元素的配置注解。
根據運行應用程序的 JVM 版本匹配的Conditional。
Spring詳解、基于 JNDI InitialContext的可用性和查找特定位置的能力匹配的Conditional。
僅當BeanFactory中已不包含滿足指定要求的 bean 時才匹配的Conditional 。 條件匹配不必滿足任何要求,并且同一bean不必滿足這些要求。
僅當指定的類不在類路徑上時才匹配的Conditional。
僅在應用程序上下文不是 Web 應用程序上下文時匹配的Conditional。
檢查指定屬性是否具有特定值的Conditional 。 默認情況下,屬性必須存在于Environment中并且不等于false 。 havingValue()和matchIfMissing()屬性允許進一步自定義。havingValue屬性可用于指定屬性應具有的值。如果該屬性根本不包含在Environment中,則matchIfMissing()屬性。 默認情況下,缺少的屬性不匹配。
@SpringBootApplication?僅當指定資源在類路徑上時才匹配的Conditional 。
僅當指定類的 bean 已包含在BeanFactory中并且可以確定單個候選者時才匹配的Conditional 。
如果BeanFactory中已包含多個匹配的 bean 實例但已定義主要候選者,則條件也將匹配; 本質上,如果自動裝配具有定義類型的 bean,則條件匹配將成功。
該條件只能匹配到目前為止已由應用程序上下文處理的 bean 定義,因此,強烈建議僅在自動配置類上使用此條件。 如果候選 bean 可能由另一個自動配置創建,請確保使用此條件的 bean 在之后運行。
當應用程序是 Web 應用程序時匹配的Conditional 。 默認情況下,任何 Web 應用程序都會匹配,但可以使用type()屬性縮小范圍。
以@ConditionalOnBean為例
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class)
public @interface ConditionalOnBean{
//...
}
@Conditional作為元注解,OnBeanCondition繼承SpringBootCondition,SpringBootCondition
Spring Framework、實現自org.springframework.context.annotation.Condition。
public abstract class SpringBootCondition implements Condition {private final Log logger = LogFactory.getLog(getClass());@Overridepublic final boolean matches(ConditionContext context,AnnotatedTypeMetadata metadata) {String classOrMethodName = getClassOrMethodName(metadata);try {ConditionOutcome outcome = getMatchOutcome(context, metadata);logOutcome(classOrMethodName, outcome);recordEvaluation(context, classOrMethodName, outcome);return outcome.isMatch();}catch (NoClassDefFoundError ex) {}}
}//org.springframework.boot.autoconfigure.condition.OnBeanCondition@Overridepublic ConditionOutcome getMatchOutcome(ConditionContext context,AnnotatedTypeMetadata metadata) {ConditionMessage matchMessage = ConditionMessage.empty();if (metadata.isAnnotated(ConditionalOnBean.class.getName())) {BeanSearchSpec spec = new BeanSearchSpec(context, metadata,ConditionalOnBean.class);MatchResult matchResult = getMatchingBeans(context, spec);if (!matchResult.isAllMatched()) {String reason = createOnBeanNoMatchReason(matchResult);return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnBean.class, spec).because(reason));}matchMessage = matchMessage.andCondition(ConditionalOnBean.class, spec).found("bean", "beans").items(Style.QUOTE, matchResult.getNamesOfAllMatches());}//...return ConditionOutcome.match(matchMessage);}
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态