我目前正在尝试配置 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 被声明。