拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Spring 条件注解

Spring 条件注解

白鹭 - 2021-11-06 2246 0 2

一、简介

在本教程中,我们将看看@Conditional注释。它用于根据定义的条件指示给定组件是否有资格注册。


我们将学习如何使用预定义的条件注释,将它们与不同的条件结合起来,以及创建我们自定义的、基于条件的注释。

2.使用Conditional注释

在我们进入实现之前,让我们首先看看我们可以在哪些情况下使用条件注释。


最常见的用法是包含或排除整个配置类:

@Configuration

 @Conditional(IsDevEnvCondition.class)

 class DevEnvLoggingConfiguration { // ...

 }

或者只是一個 bean:

@Configuration

 class DevEnvLoggingConfiguration { @Bean

 @Conditional(IsDevEnvCondition.class)

 LoggingService loggingService() { return new LoggingService();

 }

 }

通过这样做,我们可以将应用程序的行为基于给定的条件。例如,我们客户的环境类型或特定需求。在上面的例子中,我们只为开发环境初始化了额外的日志服务。


使组件有条件的另一种方法是将条件直接放在组件类上:

@Service

 @Conditional(IsDevEnvCondition.class)

 class LoggingService { // ...

 }

我们可以将上面的例子应用于任何用@Component 、 @Service 、 @Repository,或@Controller注释声明的 bean。

3. 预定义的条件注释

Spring 带有一组预定义的条件注释。让我们来看看一些最受欢迎的。

首先,让我们看看如何基于配置属性值构建组件:

@Service

 @ConditionalOnProperty(

 value="logging.enabled",

 havingValue = "true",

 matchIfMissing = true)

 class LoggingService { // ...

 }

第一个属性value,告诉我们要查看的配置属性。第二个, havingValue,定义了这个条件所需的值。最后, matchIfMissing属性告诉 Spring 如果缺少参数,是否应该匹配条件。


同样,我们可以将条件基于表达式:

@Service

 @ConditionalOnExpression(

 "${logging.enabled:true} and '${logging.level}'.equals('DEBUG')"

 )

 class LoggingService { // ...

 }

现在,只有在logging.enabled配置属性设置为true,并且logging.level设置为DEBUG.时,Spring 才会创建LoggingService


我们可以应用的另一个条件是检查是否创建了给定的 bean:

@Service

 @ConditionalOnBean(CustomLoggingConfiguration.class)

 class LoggingService { // ...

 }

或者类路径上存在给定的类:

@Service

 @ConditionalOnClass(CustomLogger.class)

 class LoggingService { // ...

 }

@ConditionalOnMissingBean或@ConditionalOnMissingClass注释来实现相反的行为。


此外,我们可以将组件依赖于给定的 Java 版本:

@Service

 @ConditionalOnJava(JavaVersion.EIGHT)

 class LoggingService { // ...

 }

在上面的例子中, LoggingService只会在运行时环境为 Java 8 时被创建。


最后,我们可以使用@ConditionalOnWarDeployment注解来只在war包中启用bean:

@Configuration

 @ConditionalOnWarDeployment

 class AdditionalWebConfiguration { // ...

 }

请注意,对于带有嵌入式服务器的应用程序,此条件将返回 false。

4.定义自定义条件

Spring 允许我们通过创建自定义条件模板来自定义@Conditional注释的行为。要创建一个,我们只需要实现Condition接口:

class Java8Condition implements Condition { @Override

 public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return JavaVersion.getJavaVersion().equals(JavaVersion.EIGHT);

 }

 }

matches方法告诉Spring条件是否已通过。它有两个参数,分别为我们提供有关 bean 将初始化的上下文和使用的@Conditional注释的元数据的信息。


如我们所见,在我们的示例中,我们只检查 Java 版本是否为 8。


之后,我们应该将我们的新条件作为@Conditional注释中的一个属性:

@Service

 @Conditional(Java8Condition.class)

 public class Java8DependedService { // ...

 }

这样, Java8DependentService将仅在从条件创建Java8Condition类匹配。

5.合并条件

对于更复杂的解决方案,我们可以使用 OR 或 AND 逻辑运算符对条件注释进行分组。


要应用 OR 运算符,我们需要创建一个扩展AnyNestedCondition类的自定义条件。在其中,我们需要static类,并使用适当的@Conditional实现对其进行注释。


例如,让我们创建一个需要 Java 8 或 Java 9 的条件:

class Java8OrJava9 extends AnyNestedCondition {



 Java8OrJava9() { super(ConfigurationPhase.REGISTER_BEAN);

 } @Conditional(Java8Condition.class)

 static class Java8 { } @Conditional(Java9Condition.class)

 static class Java9 { }



 }

另一方面,AND 运算符要简单得多。我们可以简单地将条件分组:

@Service

 @Conditional({IsWindowsCondition.class, Java8Condition.class})

 @ConditionalOnJava(JavaVersion.EIGHT)

 public class LoggingService { // ...

 }

在上面的例子中, IsWindowsCondition和Java8Condition都匹配时才会创建LoggingService

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *