【问题标题】:Spring fallback bean implementationSpring后备bean实现
【发布时间】:2015-02-28 09:45:38
【问题描述】:

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

场景

  • 有一个接口MyService
  • 我想为MyService 提供一个默认实现,我们称之为MyDefaultService
  • 如果组件扫描未检测到 MyService 的其他实现,则 Spring 应将 MyDefaultService 实例化为“后备”。
  • 如果存在 MyService 的不同实现,例如 MyCustomService,那么在将依赖项自动装配到 MyService 时,该 bean 应该始终优先于 MyDefaultService。在这方面,MyDefaultService 应该是隐性(而不是@Primary)。
  • 理想情况下,MyCustomService 上不需要附加注释即可“覆盖”MyDefaultService
  • 理想情况下,不需要显式实现的工厂或工厂方法。

问题

问题是:我需要如何注释MyDefaultService 类才能实现这一点?

到目前为止我为解决问题所做的尝试

  • @ConditionalOnMissingBean(MyService.class) 注释MyDefaultService。不起作用,因为从未使用过 MyDefaultService,即使没有其他实现 MyService
  • 有一个名为@Primary的注解解决了这个问题。但是,它需要驻留在MyCustomService 上,这是一个我尽量避免附加注释的类。本质上,我需要MyDefaultService 上的@Primaryinverse 注释。但是,我找不到这样的注释。

具体用例

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

感谢和亲切的问候,

艾伦

【问题讨论】:

    标签: spring annotations spring-boot autowired


    【解决方案1】:

    我建议编写FactoryBean 的实现来执行此操作。你的FactoryBean 会扫描bean factory 寻找实现MyService 的bean,如果找到它就会从getObject 返回那个bean。如果没有,那么它可以直接实例化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
        }
    }
    

    然后

    @Primary
    @Bean
    public MyServiceFactory MyServiceFactory() {
        return new MyServiceFactory();
    }
    

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

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

    【讨论】:

    • ListableBeanFactory beanFactory in MyServiceFactory 为空。如何解决?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 2015-10-09
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 2011-05-10
    • 2018-05-28
    相关资源
    最近更新 更多