Spring 当多个概要文件不活动时,如何有条件地声明Bean?
在我的SpringBoot应用程序中,我想根据(未加载的)Spring配置文件有条件地声明一个Bean 条件:Spring 当多个概要文件不活动时,如何有条件地声明Bean?,spring,spring-boot,Spring,Spring Boot,在我的SpringBoot应用程序中,我想根据(未加载的)Spring配置文件有条件地声明一个Bean 条件: Profile "a" NOT loaded AND Profile "b" NOT loaded 到目前为止,我的解决方案(有效): 有没有更优雅(更简短)的方式来解释这种情况? 特别是,我想摆脱这里的Spring表达式语言的用法。 < P>不幸的是,我没有一个较短的解决方案,但是如果你的情况适合于为每个配置文件创建相同的bean,你可以考虑以下方法。 @Configur
Profile "a" NOT loaded
AND
Profile "b" NOT loaded
到目前为止,我的解决方案(有效):
有没有更优雅(更简短)的方式来解释这种情况?特别是,我想摆脱这里的Spring表达式语言的用法。 < P>不幸的是,我没有一个较短的解决方案,但是如果你的情况适合于为每个配置文件创建相同的bean,你可以考虑以下方法。
@Configuration
public class MyBeanConfiguration {
@Bean
@Profile("a")
public MyBean myBeanForA() {/*...*/}
@Bean
@Profile("b")
public MyBean myBeanForB() {/*...*/}
@Bean
@ConditionalOnMissingBean(MyBean.class)
public MyBean myBeanForOthers() {/*...*/}
}
如果您有一个单独的概要文件,您可以简单地使用not操作符的
@profile
注释。它还接受多个配置文件,但带有或
条件
因此,另一种解决方案是使用自定义注释。像这样:
public class SomeCustomCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// Return true if NOT "a" AND NOT "b"
return !context.getEnvironment().acceptsProfiles("a")
&& !context.getEnvironment().acceptsProfiles("b");
}
}
然后用它注释您的方法,如:
@Bean
@Conditional(SomeCustomCondition.class)
public MyBean myBean(){/*...*/}
我更喜欢这种解决方案,它更详细,但仅适用于两种配置文件:
@Profile("!a")
@Configuration
public class NoAConfig {
@Profile("!b")
@Configuration
public static class NoBConfig {
@Bean
public MyBean myBean(){
return new MyBean();
}
}
}
由于Spring 5.1.4(包含在Spring Boot 2.1.2中),所以可以在配置文件字符串注释中使用配置文件表达式。因此:
在Spring 5.1.4(弹簧靴2.1.2)及以上版本中的操作非常简单:
@Component
@Profile("!a & !b")
public class MyComponent {}
在Spring 4.x和5.0.x中:
今春的版本有很多方法,每种方法都有其优点和缺点。当没有太多的组合可以覆盖时,我个人喜欢使用@Conditional
注释
在类似问题中可以找到其他方法:
对于5.0.x及以下的Spring版本/Spring Boot 2.0.x,它的一个变体更具可读性
public class SomeCustomCondition implements Condition {
@Override
public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) {
final Environment environment = context.getEnvironment();
// true if profile is NOT "a" AND NOT "b" AND NOT "c"
return !environment.acceptsProfiles("a", "b", "c");
}
}
有关较新版本的Spring/Spring Boot,请参阅。谢谢,但这不适合我。假设我们加载了Profile
a
和b
,那么在这种情况下,MyBean
会加载两次,通常我们不希望出现这种行为。第二件事是,这不是我问题的解决方案。当两个配置文件都未加载时,也不应声明MyBean
。像这样使用@conditionalnmissingbean
是危险的。为了安全起见,它应该只用于自动配置类谢谢你们的评论,伙计们。我曾经使用配置文件作为与环境相关的配置属性束,如“dev”、“test”等。实际上,如果两个配置文件都已加载,则无法使用这种方法。谢谢,我喜欢这种方法+1用于使用条件
。我会等一段时间再接受这个答案。也许还有另一个更优雅的建议;-)(但我不这么认为)我在上面尝试了同样的方法,但出于某种原因,它忽略了@Conditional注释。有什么建议吗?太好了!这应该是现在可以接受的答案:-)对于这个特定的情况(双重否定),您需要额外确保它是spring core:5.1.4+/spring boot:2.1.2+,因为在这些版本之前有一个严重的错误:
public class SomeCustomCondition implements Condition {
@Override
public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) {
final Environment environment = context.getEnvironment();
// true if profile is NOT "a" AND NOT "b" AND NOT "c"
return !environment.acceptsProfiles("a", "b", "c");
}
}