我目前正在尝试配置 Spring Boot (使用 Java 注释 和 ComponentScan )用于以下场景:
场景
MyService . MyService 提供一个默认实现,我们称之为MyDefaultService . MyService 的其他实现, Spring 应该实例化 MyDefaultService作为“后备”。 MyService 有不同的实现现在,比如说MyCustomService , 那么那个 bean 应该 总是 优先于 MyDefaultService将依赖项 Autowiring 到 MyService 时.在这方面,MyDefaultService应该是 隐性 (相对于 @Primary )。 MyCustomService 上不需要附加注释。让它“覆盖”MyDefaultService . 问题
问题是:我需要如何注释
MyDefaultService为了达到这个目的上课?
到目前为止我尝试解决的问题
MyDefaultService与 @ConditionalOnMissingBean(MyService.class) .没有工作,因为 MyDefaultService从未使用过,即使没有 MyService 的其他实现. @Primary解决了这个问题。但是,它需要驻留在 MyCustomService 上。 ,我试图避免附加注释的类。本质上,我需要 @Primary 的反注释在 MyDefaultService .但是,我找不到这样的注释。 具体用例
我正在一个项目中开发一个服务层,而另一个项目将在它之上实现一个 Web UI 层。 UI 项目依赖于服务层项目。但是,对于在服务层实现的某些功能,我需要知道当前在 Web 上下文中登录的用户。所以我必须在服务层项目中为其定义一个服务接口(interface),以便它可以由UI项目实现。但是,为了在服务层项目中进行测试,我需要该接口(interface)的默认实现。此外,如果 UI 项目团队忘记实现此接口(interface),应用程序不应崩溃,而是实例化 fallback bean 并发出警告。
谢谢和亲切的问候,
艾伦
请您参考如下方法:
我建议编写 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 用于注入(inject)。
这个解决方案不需要任何特殊的魔法,而且它的工作原理相当明显。您还可以处理错误情况,例如多个
MyService bean 被声明。




