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();
    }

}