Spring Boot测试场景下ConfigProperties为空时如何不创建DataSource Bean
解决方案1:直接在Bean创建方法中判断返回null
Spring 3.0及以上版本支持@Bean方法返回null时,容器不会注册对应的Bean实例,直接在DataSource创建逻辑里加判断即可:
@Configuration public class DataSourceConfig { @Autowired(required = false) private ConfigProperties configProperties; @Bean public DataSource dataSource() { if (configProperties == null || configProperties.getUsername() == null || configProperties.getUrl() == null) { return null; } return DataSourceBuilder.create() .username(configProperties.getUsername()) .password(configProperties.getPassword()) .url(configProperties.getUrl()) .build(); } }
注意@Autowired要加required = false,避免ConfigProperties未初始化时注入报错。如果后续有依赖DataSource的Bean需要兼容测试场景,也给对应的@Autowired加required = false,或者配合@ConditionalOnBean(DataSource.class)使用即可。
解决方案2:自定义Condition直接从环境变量读取配置
如果需要用条件注解实现,不要在Condition类里注入ConfigProperties,直接从ConditionContext拿到Environment读取配置源的原始值,完全避开Bean初始化顺序问题:
首先给DataSource Bean加条件注解:
@Configuration public class DataSourceConfig { @Bean @Conditional(DataSourceCondition.class) public DataSource dataSource(ConfigProperties configProperties) { return DataSourceBuilder.create() .username(configProperties.getUsername()) .password(configProperties.getPassword()) .url(configProperties.getUrl()) .build(); } }
然后实现Condition类,将代码里的db.config替换为你ConfigProperties类上@ConfigurationProperties注解对应的前缀即可:
public class DataSourceCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Environment env = context.getEnvironment(); String username = env.getProperty("db.config.username"); String url = env.getProperty("db.config.url"); return username != null && url != null; } }
解决方案3:使用@ConditionalOnExpression注解
你之前的SpEL写法问题在于直接引用了还未初始化的configProperties Bean,正确写法直接从环境变量取属性即可:
@Bean @ConditionalOnExpression("'${db.config.username:}' != '' && '${db.config.url:}' != ''") public DataSource dataSource(ConfigProperties configProperties) { return DataSourceBuilder.create() .username(configProperties.getUsername()) .password(configProperties.getPassword()) .url(configProperties.getUrl()) .build(); }
表达式里的:''是默认值配置,避免属性不存在时SpEL解析报错,同样要替换db.config为你实际的配置前缀。
内容的提问来源于stack exchange,提问作者user3740495
相关产品推荐
相关产品推荐

