基本上我想创建一个具体的bean,如果设置了一个属性,并且某种 NoopBean 具有相同的接口,但什么都不做。
最干净的方法是什么?
答案 0 :(得分:6)
您可以将对象描述为bean,其中创建取决于您的自定义条件。配置可能如下所示:
@Configuration
public class YourConfiguration {
@Bean(name="concreteBean")
@Conditional(YourCondition.class)
public YourInterface concreteBean(){
return new ConcreteBean();
}
@Bean(name="noopBean")
@Conditional(YourCondition.class)
public YourInterface noopBean(){
return new NoopBean();
}
}
@Conditional注释也可以与注释为@Component
的类一起使用,这些类依赖于组件扫描过程。
您还需要一个描述条件的类,例如:
public class YourCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return "concret".equals(context.getEnvironment().getProperty("your.property"));
}
}
有一个描述条件的类是高度灵活的,但是如果你只是想检查一个属性,你可以使用更@Condition
@ConditionalOnProperty的更专业版本并摆脱它条件类。在这种情况下,您可以直接在bean的注释中描述条件。
@ConditionalOnProperty(name="your.property", havingValue="concret")
在这种情况下的缺点是你需要在每个bean中重复相同的条件。建议使用带有单独类的简单@Conditional
,因为它可以获得正确有意义的名称。
答案 1 :(得分:1)
一个选项是:
@Bean
public MyInterface myBean() {
if (somePropertySet) {
return new RealBean();
} else {
return new NoOpBean();
}
}
另一种选择是使用弹簧轮廓。
@Bean
@Profile("noop-profile")
public MyInterface myBean() {
return new NoOpBean();
}
@Bean
@Profile("real-profile")
public MyInterface myBean() {
return new RealBean();
}
如果您已经使用弹簧轮廓(例如“生产”,“舞台”等),第二个选项可能有意义。