Spring Authorization Server,Spring之@Conditional

 2023-12-12 阅读 27 评论 0

摘要:@Conditional @Conditional注解可以說是SpringBoot的條件注解,表示組件只有在所有指定條件都匹配時才有資格注冊,條件是可以在 bean 定義注冊之前??以編程方式確定的任何狀態,@Conditional注解可以通過以下任何方式使用: 作為直接或間

@Conditional

@Conditional注解可以說是SpringBoot的條件注解,表示組件只有在所有指定條件都匹配時才有資格注冊,條件是可以在 bean 定義注冊之前??以編程方式確定的任何狀態,@Conditional注解可以通過以下任何方式使用:

  • 作為直接或間接使用@Component注解的任何類的類型級注釋,包括@Configuration類
  • 作為元注解,用于編寫自定義構造型注釋
  • 作為任何@Bean方法的方法級注解

如果@Configuration類被標記為@Conditional ,那么與該類關聯的所有@Bean方法、 @Import 注解和@ComponentScan注解都將受制于條件。

SpringBoot @ConditionalOn*

SpringBoot提供的@ConditionalOn*的注解都是基于@Conditional注解實現

@ConditionalOnBean

Spring Authorization Server?僅當滿足所有指定要求的 bean 已包含在BeanFactory中時才匹配的Conditional 。 必須滿足所有要求才能匹配條件,但不必由同一個 bean 滿足。

@ConditionalOnClass

僅當指定的類在類路徑上時才匹配的Conditional 。
可以在@Configuration類上安全地指定value() ,因為在加載類之前使用 ASM 解析注釋元數據。 放置在@Bean方法上時需要格外小心,考慮將條件隔離在單獨的Configuration類中,特別是如果方法的返回類型與value()中的值匹配。

@ConditionalOnCloudPlatform

當指定的云平臺處于活動狀態時匹配的Conditional。?

@ConditionalOnExpression

取決于 SpEL 表達式的值的條件元素的配置注解。

@ConditionalOnJava

根據運行應用程序的 JVM 版本匹配的Conditional。

@ConditionalOnJndi

Spring詳解、基于 JNDI InitialContext的可用性和查找特定位置的能力匹配的Conditional。

@ConditionalOnMissingBean

僅當BeanFactory中已不包含滿足指定要求的 bean 時才匹配的Conditional 。 條件匹配不必滿足任何要求,并且同一bean不必滿足這些要求。

@ConditionalOnMissingClass

僅當指定的類不在類路徑上時才匹配的Conditional。

@ConditionalOnNotWebApplication

僅在應用程序上下文不是 Web 應用程序上下文時匹配的Conditional。

@ConditionalOnProperty

檢查指定屬性是否具有特定值的Conditional 。 默認情況下,屬性必須存在于Environment中并且不等于false 。 havingValue()和matchIfMissing()屬性允許進一步自定義。havingValue屬性可用于指定屬性應具有的值。如果該屬性根本不包含在Environment中,則matchIfMissing()屬性。 默認情況下,缺少的屬性不匹配。

@ConditionalOnResource

@SpringBootApplication?僅當指定資源在類路徑上時才匹配的Conditional 。

@ConditionalOnSingleCandidate

僅當指定類的 bean 已包含在BeanFactory中并且可以確定單個候選者時才匹配的Conditional 。
如果BeanFactory中已包含多個匹配的 bean 實例但已定義主要候選者,則條件也將匹配; 本質上,如果自動裝配具有定義類型的 bean,則條件匹配將成功。
該條件只能匹配到目前為止已由應用程序上下文處理的 bean 定義,因此,強烈建議僅在自動配置類上使用此條件。 如果候選 bean 可能由另一個自動配置創建,請確保使用此條件的 bean 在之后運行。

@ConditionalOnWebApplication

當應用程序是 Web 應用程序時匹配的Conditional 。 默認情況下,任何 Web 應用程序都會匹配,但可以使用type()屬性縮小范圍。

@ConditionalOn*實現原理

以@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);}

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

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

发表评论:

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

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

底部版权信息