我目前正在尝试针对以下情况配置 Spring Boot (使用 Java注释和 ComponentScan ):
方案
MyService
。MyService
提供一个默认实现,我们称之为MyDefaultService
。MyService
的其他实现,则Spring应将MyDefaultService
实例化为“后备”。MyService
的不同实现,让我们说MyCustomService
,那么当自动装配依赖关系时,该bean应始终优先于MyDefaultService
MyService
。在这方面,MyDefaultService
应该隐性(而不是@Primary
)。MyCustomService
上不需要额外的注释,以使其“覆盖”MyDefaultService
。问题
问题是:为了达到这个目的,我如何需要注释MyDefaultService
类?
到目前为止我尝试解决问题
MyDefaultService
注释@ConditionalOnMissingBean(MyService.class)
。因为MyDefaultService
从未使用过,所以没有用,即使没有MyService
的其他实现。@Primary
的注释可以解决问题。但是,它需要驻留在MyCustomService
上,这是一个我试图保留其他注释的类。基本上,我需要@Primary
上MyDefaultService
的逆注释。但是,我找不到这样的注释。具体用例
我正在一个项目中开发一个服务层,另一个项目将在它上面实现一个Web UI层。 UI项目依赖于服务层项目。但是,对于在服务层实现的某些功能,我需要知道哪个用户当前在Web上下文中登录。所以我必须在服务层项目中为它定义一个服务接口,这样它就可以由UI项目实现。但是,为了在服务层项目中进行测试,我需要该接口的默认实现。此外,如果UI项目团队忘记实现此接口,则应用程序不应该崩溃,而是实例化回退bean并发出警告。
谢谢&亲切的问候,
艾伦
答案 0 :(得分:3)
我建议编写FactoryBean
的实现来执行此操作。您的FactoryBean
将扫描bean工厂,查找实现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。