我目前在我的applications.yaml文件的String属性条件下创建dataSource 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
答案 0 :(得分:3)
我遇到了同样的问题。由于我不知所措,你在寻找“财产存在而非空”的条件。这种情况不是开箱即用的,因此需要一些编码。使用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")
将按预期为您服务。
答案 1 :(得分:1)
您可以尝试更通用的注释,这是Spring Core的标准:
org.springframework.context.annotation.Conditional
。
在回调的上下文对象中,您可以获得所需的所有信息:org.springframework.context.annotation.Condition
您也可以考虑使用个人资料。
答案 2 :(得分:0)
您可以将@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
}