SpEL @ConditionalOnProperty 字符串属性为空或 null
Posted
技术标签:
【中文标题】SpEL @ConditionalOnProperty 字符串属性为空或 null【英文标题】:SpEL @ConditionalOnProperty string property empty or nulll 【发布时间】: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
参数来控制当属性不存在时会发生什么。您是想说空字符串值是代码中不存在的同义词吗?
【参考方案1】:
您可以使用 @ConditionalOnExpression
和 Spring 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
【讨论】:
我可以知道为什么我们需要泛型类型吗? T(org.springframework.util.StringUtils) @HongT(..)
是引用类型,与泛型无关。我假设您正在考虑<T>
。这是 SpEL 参考:docs.spring.io/spring-framework/docs/current/reference/html/…【参考方案2】:
我也有同样的问题。正如我所不明白的那样,您正在寻找“财产存在且不为空”的条件。这种情况不是开箱即用的,因此需要一些编码。使用org.springframework.context.annotation.Conditional
的解决方案对我有用:
创建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();
用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
您也可以考虑使用个人资料。
【讨论】:
以上是关于SpEL @ConditionalOnProperty 字符串属性为空或 null的主要内容,如果未能解决你的问题,请参考以下文章