Spring fallback bean实现

Ala*_*n47 7 spring annotations autowired spring-boot

我目前正在尝试为以下场景配置Spring Boot(使用Java AnnotationsComponentScan):

脚本

  • 有一个界面MyService.
  • 我想提供一个默认实现MyService,让我们调用它MyDefaultService.
  • 如果组件扫描没有检测到其他实现MyService,Spring应该实例MyDefaultService化为"后备".
  • 如果存在不同的MyServicepresent 实现MyCustomService,那么,那么该bean应始终优先于MyDefaultService自动装配依赖关系MyService.在这方面,MyDefaultService应该是隐性的(而不是@Primary).
  • 理想情况下,不需要额外注释就MyCustomService可以"覆盖"它MyDefaultService.
  • 理想情况下,不需要明确实施的工厂或工厂方法.

问题是:MyDefaultService为了实现这一目标,我如何需要注释类?

到目前为止我试图解决这个问题

  • MyDefaultService@ConditionalOnMissingBean(MyService.class).注释.MyDefaultService没用,因为从未使用过,即使没有其他实现MyService.
  • 有一个称为@Primary解决问题的注释.但是,它需要驻留在MyCustomService一个我试图保持没有其他注释的类.基本上,我需要on 的反向注释.但是,我找不到这样的注释.@PrimaryMyDefaultService

具体用例

我正在一个项目中开发一个服务层,另一个项目将在它上面实现一个Web UI层.UI项目依赖于服务层项目.但是,对于在服务层实现的某些功能,我需要知道哪个用户当前在Web上下文中登录.所以我必须在服务层项目中为它定义一个服务接口,这样它就可以由UI项目实现.但是,为了在服务层项目中进行测试,我需要该接口的默认实现.此外,如果UI项目团队忘记实现此接口,则应用程序不应该崩溃,而是实例化回退bean并发出警​​告.

谢谢和亲切的问候,

艾伦

ska*_*man 6

我建议编写一个实现FactoryBean来做到这一点。您FactoryBean将扫描 bean 工厂以寻找实现 的 bean,MyService如果找到,则从 返回该 bean getObject。如果没有,那么它可以MyDefaultService直接实例化并返回。然后您的工厂 bean 被注释为@Primary.

所以像这样的片段(伪代码):

public class MyServiceFactory implements FactoryBean<MyService> {
    ListableBeanFactory beanFactory;

    public MyService getObject() {
        Map beans = beanFactory.getBeansOfType(MyService.class)
        if (beans.isEmpty())
            return new MyDefaultService(); // plus args, obviously
        else
            return get_some_bean_from_the_map
    }
}
Run Code Online (Sandbox Code Playgroud)

进而

@Primary
@Bean
public MyServiceFactory MyServiceFactory() {
    return new MyServiceFactory();
}
Run Code Online (Sandbox Code Playgroud)

Spring 将自动处理工厂 bean(即,它将像平常一样使MyService对象作为注入的 bean 可用。

这个解决方案不需要任何特殊的魔法,它的工作原理是相当明显的。您还可以处理错误的情况,例如MyService声明多个bean。