大数跨境
0
0

SpringBoot这些条件注解助你高效开发

SpringBoot这些条件注解助你高效开发 Spring全家桶实战案例
2024-03-19
2
导读:SpringBoot这些条件注解可能帮你大忙

环境:SpringBoot2.7.16



1. 简介

Spring Boot 包含大量 @Conditional 注解,你可以通过注解 @Configuration 类或单个 @Bean 方法在自己的代码中重复使用这些注解。这些注解包括:

  • Class Conditions

    在类上添加的条件注解。

  • Bean Conditions

    在方法上使用@Bean注解时使用注解。

  • Property Conditions

    根据属性配置判断条件注解。

  • Resource Conditions

    根据资源判断条件注解

  • Web Application Conditions

    针对web环境的注解

  • SpEL Expression Conditions

    可以使用SpEL表达式的注解


2. Class Conditions

@ConditionalOnClass 和 @ConditionalOnMissingClass 注解使 @Configuration 类可以根据特定类的存在或不存在而被包含。如下例所示:

@Configuration(proxyBeanMethods = false)@ConditionalOnClass(CustomLogImpl.class)public class PackConfiguration {  @Bean  public LogAspect logAspect() {    // ...  }}

如果使用 @ConditionalOnClass 或 @ConditionalOnMissingClass 作为元注解的一部分来编写自己的组成注解,则必须使用 name,因为在这种情况下对类的引用不会被处理。


3. Bean Conditions

@ConditionalOnBean 和 @ConditionalOnMissingBean 注解允许根据特定 Bean 的存在或不存在来包含 Bean。你可以使用 value 属性按类型指定 Bean,也可以使用 name 属性按名称指定 Bean。搜索属性可让你限制在搜索 Bean 时应考虑的 ApplicationContext 层次结构。

@Configurationpublic class PackConfiguration {  // 指定只能在当前容器中查找,如果存在父容器不会在父容器中查找  // 这里的默认值是ALL  @Bean  @ConditionalOnMissingBean(search = SearchStrategy.CURRENT)  public UserService userService() {    return new UserService ();  }}

需要非常注意添加 Bean 定义的顺序,因为这些条件是根据目前已处理的内容进行评估的。

注意:@ConditionalOnBean@ConditionalOnMissingBean 不会阻止 @Configuration 类的创建。在类级别使用这些条件与使用注解标记每个包含的 @Bean 方法之间的唯一区别是,如果条件不匹配,前者会阻止将 @Configuration 类注册为 Bean。

4. Property Conditions

@ConditionalOnProperty 注解允许根据 Spring 环境属性进行配置。使用前缀和名称属性指定应检查的属性。默认情况下,任何存在且不等于 false 的属性都会被匹配。你还可以使用 havingValue 和 matchIfMissing 属性创建更高级的检查。

@Configurationpublic class PropertyCondition {    @Bean  @ConditionalOnProperty(prefix = "pack.config", name = "enabled", havingValue = "true", matchIfMissing = true)  public AnimalService animalService() {    return new AnimalService() ;  }  }

当配置文件中的pack.config.enabled=true或者没有配置时,条件都成立。

5. Resource Conditions

@ConditionalOnResource 注解允许配置仅在特定资源存在时才被包含。资源可通过使用通常的 Spring 约定来指定,如下例所示:

@Configurationpublic class PropertyCondition {    @Bean  @ConditionalOnResource(resources = {"classpath:config.properties"})  public AnimalService animalService() {    return new AnimalService() ;  }}

当类路径下存在config.properties文件时才会创建上面的AnimalService。

6. Web Application Conditions

通过 @ConditionalOnWebApplication 和 @ConditionalOnNotWebApplication 注解,可以根据应用程序是否是 Web 应用程序来进行配置。基于 servlet 的 Web 应用程序是指使用 Spring WebApplicationContext、定义会话作用域或具有 ConfigurableWebEnvironment 的任何应用程序。反应式网络应用是指使用 ReactiveWebApplicationContext 或具有 ConfigurableReactiveWebEnvironment 的任何应用。
通过 @ConditionalOnWarDeployment 和 @ConditionalOnNotWarDeployment 注解,可以根据应用程序是否是部署到 servlet 容器的传统 WAR 应用程序来进行配置。对于使用嵌入式 Web 服务器运行的应用程序,此条件将不匹配。

@Configurationpublic class PropertyCondition {    @Bean  @ConditionalOnWebApplication(type = Type.REACTIVE)  public AnimalService animalService() {    return new AnimalService() ;  }}

只有当前环境是基于反应式的才会创建Bean,反应式的条件是项目中引入的是webflux(不能同时存在web,否则以servlet为主)。

7. SpEL Expression Conditions

@ConditionalOnExpression注解允许根据 SpEL 表达式的结果加入配置。

@Configurationpublic class PropertyCondition {    @Bean  @ConditionalOnExpression("#{'true'.equals('${pack.config.enabled}')}")  public AnimalService animalService() {    return new AnimalService() ;  }  }


8. 自定义Condition

自定义条件匹配类

public class PackConditionProperty implements Condition {
@Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Boolean result = context.getEnvironment().getProperty("pack.config.enabled", Boolean.class, true) ; return result ; }
}

自定义注解

@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD, ElementType.TYPE})@Conditional({PackConditionProperty.class})public @interface PackCondition {}

通过@Conditional注解添加上面的条件类。

以上是本篇文章的全部内容,希望对你有帮助。

完毕!!!

【声明】内容源于网络
0
0
Spring全家桶实战案例
Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
内容 832
粉丝 0
Spring全家桶实战案例 Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
总阅读38
粉丝0
内容832