【问题标题】:SpEL @ConditionalOnProperty string property empty or nulllSpEL @ConditionalOnProperty 字符串属性为空或 null
【发布时间】:2018-02-17 12:23:16
【问题描述】:

我目前在使用我的 applications.yaml 文件中的 String 属性创建数据源 bean 时遇到问题。

理想情况下,我只想在我的 application.yaml 文件中设置 url 时创建 dataSource bean。如果 bean 不存在(空或 null),则不应创建它。我知道这个条件会检查布尔值,但无论如何要检查字符串属性是空还是空?

DatabaseConfig.java

@Configuration
public class DatabaseConfig {
    @Value("${database.url:}")
    private String databaseUrl;

    @Value("${database.username:}")
    private String databaseUsername;

    @Value("${database.password:}")
    private String databasePassword;

    protected static final String DRIVER_CLASS_NAME = "com.sybase.jdbc4.jdbc.SybDriver";


    /**
     * Configures and returns a datasource. Optional
     *
     * @return A datasource.
     */
    @ConditionalOnProperty(value = "database.url")
    @Bean
    public DataSource dataSource() {
        return DataSourceBuilder.create()
            .url(testDatabaseUrl)
            .username(testDatabaseUsername)
            .password(testDatabasePassword)
            .build();
    }
}

application.yml(该字段是可选的)

database:
  url: http://localhost:9000

【问题讨论】:

  • @ConditionalOnProperty 已经有一个 matchIfMissing 参数来控制当属性不存在时会发生什么。您是想说空字符串值是代码中不存在的同义词吗?

标签: java spring spring-boot datasource spring-el


【解决方案1】:

您可以使用 @ConditionalOnExpressionSpring Expression Language (SpEL) 表达式作为值:

@ConditionalOnExpression("!T(org.springframework.util.StringUtils).isEmpty('${database.url:}')")
@Bean
public DataSource dataSource() {
    // snip
}

为了更好的可读性和可重用性,您可以将其变成注释:

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ConditionalOnExpression("!T(org.springframework.util.StringUtils).isEmpty('${database.url:}')")
public @interface ConditionalOnDatabaseUrl {
}

@ConditionalOnDatabaseUrl
@Bean
public DataSource dataSource() {
    // snip
}

【讨论】:

【解决方案2】:

我也有同样的问题。正如我所不明白的那样,您正在寻找“财产存在且不为空”的条件。这种情况不是开箱即用的,因此需要一些编码。使用org.springframework.context.annotation.Conditional 的解决方案对我有用:

  1. 创建ConditionalOnPropertyNotEmpty注解并伴随OnPropertyNotEmptyCondition类如下:

    // ConditionalOnPropertyNotEmpty.java
    
    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.context.annotation.Conditional;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import java.util.Map;
    
    @Target({ ElementType.TYPE, ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    @Conditional(ConditionalOnPropertyNotEmpty.OnPropertyNotEmptyCondition.class)
    public @interface ConditionalOnPropertyNotEmpty {
        String value();
    
        class OnPropertyNotEmptyCondition implements Condition {
    
            @Override
            public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
                Map<String, Object> attrs = metadata.getAnnotationAttributes(ConditionalOnPropertyNotEmpty.class.getName());
                String propertyName = (String) attrs.get("value");
                String val = context.getEnvironment().getProperty(propertyName);
                return val != null && !val.trim().isEmpty();
            }
        }
    }
    
  2. ConditionalOnPropertyNotEmpty注释你的bean,比如:

    @ConditionalOnPropertyNotEmpty("database.url")
    @Bean
    public DataSource dataSource() { ... }
    

--

或者,您可以将 detabase.url 显式设置为 false(例如 detabase.url: false),或者在您的配置中根本不定义 detabase.url。然后,@ConditionalOnProperty(value = "database.url") 将按预期为您工作。

【讨论】:

    【解决方案3】:

    您可以尝试更通用的注释,这是 Spring Core 的标准: org.springframework.context.annotation.Conditional

    在回调的上下文对象中,您可以获得所需的所有信息:org.springframework.context.annotation.Condition

    您也可以考虑使用个人资料。

    【讨论】:

      猜你喜欢
      • 2012-11-28
      • 2012-01-25
      • 2012-06-12
      • 1970-01-01
      • 2017-08-20
      • 1970-01-01
      • 2017-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多