开发者社区> 问答> 正文

Spring以合格的Bean为条件

@ConditionalOnBean在Spring中如何与预选赛一起使用?

以下是独立的示例场景:我有

  • 服务接口 SomeService
  • 适配器接口 SomeAdapter
  • with qualifier 的GreenService实现,具体取决于with qualifierSomeService@GreenSomeAdapter@Green
  • with qualifier 的BlueService实现,具体取决于with qualifierSomeService@BlueSomeAdapter@Blue
  • with限定符的可选GreenAdapter实现SomeAdapter@Green
  • with限定符的可选BlueAdapter实现SomeAdapter@Blue

@绿色预选赛:

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Green { }

@Blue限定词:

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Blue {  }

绿色服务:

@Green
@Service
@ConditionalOnBean(value = SomeAdapter.class, annotation = Green.class)
public class GreenService implements SomeService {

    @Autowired
    @Green
    private SomeAdapter adapter;
}

BlueService:

@Blue
@Service
@ConditionalOnBean(value = SomeAdapter.class, annotation = Blue.class)
public class BlueService implements SomeService {

    @Autowired
    @Blue
    private SomeAdapter adapter;
}

绿色适配器:

@Green
@Component
public class GreenAdapter implements SomeAdapter {}
BlueAdapter:

@Blue
@Component
public class BlueAdapter implements SomeAdapter {}
测试以检查Bean的激活情况(不包含BlueAdapter,因此BlueService不会处于活动状态):

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {GreenService.class, BlueService.class, GreenAdapter.class})
public class GreenBlueServiceTest {

    @Autowired
    @Green
    private Optional<SomeService> greenService;

    @Autowired
    @Blue
    private Optional<SomeService> blueService;

    @Test
    public void testGreen() {
        assertTrue(greenService.isPresent());
    }

    @Test
    public void testBlue() {
        assertFalse(blueService.isPresent());
    }
}

问题:测试将无法运行,报告一个丢失的依赖(SomeAdapter有资格@Blue的BlueService)。的@ConditionalOnBean,因为没有应禁用豆SomeAdapter与资格赛@Blue,但这并没有工作。

我发现,当我向中添加@TrueBlue注释(与@Blue,但未标记为@Annotation)并在上BlueAdapter使用该注释进行Bean激活时BlueService,它的工作原理与预期的一样(测试所有绿色)。

结论:

  • 带有必需注释的条件Bean激活有效(原则上)
  • 但是,当所需注释为 @Qualifier 这是bug还是按设计,我如何才能实现这种依赖Spring中合格bean的条件激活?

问题来源:Stack Overflow

展开
收起
montos 2020-03-26 23:02:35 365 0
1 条回答
写回答
取消 提交回答
  • 请注意@ConditionalOnBean文档说:

    All the requirements must be met for the condition to match, but they do not have to be met by the same bean. ` 
    

    注意说的部分 but they do not have to be met by the same bean.

    如果存在类型中的任何豆SomeAdapter加上任何带注释的豆,则下面的条件将匹配@Blue

    @ConditionalOnBean(value = SomeAdapter.class, annotation = Blue.class)
    

    因此,当你有BlueService豆标注有@Blue你也有GreenAdapter这是一个SomeAdapter.class条件通过。它欺骗我们以为它只会与SomeAdapter带有@Blue注释的匹配。

    为了使您的示例正常工作,只需@Blue从中删除注释BlueService

    问题来源:Stack Overflow

    2020-03-26 23:03:16
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧 立即下载
微服务架构模式与原理Spring Cloud开发实战 立即下载
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载

相关实验场景

更多