SpringBoot:如何注入具有相同名称的两个类
在我的应用程序中,我有两个名称相同的类,当然是在不同的包中 这两个类都需要在应用程序中注入;很遗憾,我收到以下错误消息:SpringBoot:如何注入具有相同名称的两个类,spring,spring-boot,dependency-injection,guice,Spring,Spring Boot,Dependency Injection,Guice,在我的应用程序中,我有两个名称相同的类,当然是在不同的包中 这两个类都需要在应用程序中注入;很遗憾,我收到以下错误消息: Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'myFeature' for bean class [org.pmesmeur.springboot.training.service.fea
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'myFeature' for bean class [org.pmesmeur.springboot.training.service.feature2.MyFeature] conflicts with existing, non-compatible bean definition of same name and class [org.pmesmeur.springboot.training.service.feature1.MyFeature]
我的问题可以通过以下样本复制:
@Component
@EnableConfigurationProperties(ServiceProperties.class)
public class MyService implements IService {
private final ServiceProperties serviceProperties;
private final IProvider provider;
private final org.pmesmeur.springboot.training.service.feature1.IMyFeature f1;
private final org.pmesmeur.springboot.training.service.feature2.IMyFeature f2;
@Autowired
public MyService(ServiceProperties serviceProperties,
IProvider provider,
org.pmesmeur.springboot.training.service.feature1.IMyFeature f1,
org.pmesmeur.springboot.training.service.feature2.IMyFeature f2) {
this.serviceProperties = serviceProperties;
this.provider = provider;
this.f1 = f1;
this.f2 = f2;
}
...
如果我对我的类使用不同的名称
MyFeature
,我的问题就消失了
我习惯于使用Guice,并且这个框架没有这种问题/限制
spring依赖项注入框架似乎只使用
类名称,而不是包名称+类名,以便
选择它的类
在“现实生活”中,我遇到了一个更大的项目的问题,我强烈希望不必重命名我的类:有人能帮我吗
最后一点,我宁愿避免使用诸如
@Qualifier(value=“ABC”)
在注入我的类时:在我的示例中,
要找到正确的实例,不应存在歧义
MyFeature
,因为它们没有实现相同的接口
您可以为每个组件分配一个值,例如
@component(value=“someBean”)
,然后将@限定符注入其中,例如
@Autowired
public SomeService(@Qualifier("someBean") Some s){
//....
}
你可以这样做
在包a中
public class MyFeature implements IMyFeature {
@Override
public void print() {
System.out.print("FooBar");
}
}
包装内b
public class MyFeature implements IMyFeature {
@Override
public void print() {
System.out.print("HelloWorld");
}
}
在某些方面
然后可以使用名称f1
和f2
自动关联它们,这是它们各自的bean构造函数方法的名称
您可以使用@组件(“f1”)
&
@组件(“f2”)
即使实现了不同的接口,并且在不同的包中,相同的bean名称也会导致这种问题,并且您必须使用某种自定义命名来区分。与使用上述解决方案相比,使用某些解决方案会非常难看。Spring提供了按类型和名称自动连线。你的类名是一样的。默认情况下,spring只考虑类名而不考虑包。但您可以通过定义BeanNameGenerator接口的自定义实现来覆盖此行为,在该接口中,您可以使用包和名称生成名称。我不提供代码解决方案,因为我认为您应该在这方面进行更多的探索。简单地重新实现beannamagenerator
为按名称声明/实例化的bean添加了一个新问题
@Component("HelloWorld")
class MyComponent implements IComponent {
...
}
@Qualifier(value = "HelloWorld") IComponent component
我通过扩展AnnotationBeanNameGenerator
并重新定义方法buildDefaultBeanName()
当来自diff包的两个接口都具有相同的抽象方法时,为什么不能使用单个接口?您是否在项目中的任何地方使用@Bean
注释?您能否对我的答案给出一些反馈?我想帮助完成这个问题!!
@Autowired
public SomeService(@Qualifier("someBean") Some s){
//....
}
public class MyFeature implements IMyFeature {
@Override
public void print() {
System.out.print("FooBar");
}
}
public class MyFeature implements IMyFeature {
@Override
public void print() {
System.out.print("HelloWorld");
}
}
@Configuration
public class Configuration {
@Bean
public a.MyFeature f1() {
return new a.MyFeature();
}
@Bean
public b.MyFeature f2() {
return new b.MyFeature();
}
}
@Component("HelloWorld")
class MyComponent implements IComponent {
...
}
@Qualifier(value = "HelloWorld") IComponent component
static class BeanNameGeneratorIncludingPackageName extends AnnotationBeanNameGenerator {
public BeanNameGeneratorIncludingPackageName() {
}
@Override
public String buildDefaultBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
return beanDefinition.getBeanClassName();
}
}