SpringBoot : how to inject two classes having same name

标签 spring spring-boot dependency-injection guice

在我的应用程序中,我有两个具有相同名称的类,但当然位于不同的包中。

这两个类都需要注入(inject)到应用程序中;不幸的是,我收到以下错误消息:

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;
    }
    ...
<小时/>
package org.pmesmeur.springboot.training.service.feature1;

public interface IMyFeature {

    void print();

}
<小时/>
package org.pmesmeur.springboot.training.service.feature1;

import org.springframework.stereotype.Component;

@Component
public class MyFeature implements IMyFeature {

    @Override
    public void print() {
        System.out.print("HelloWorld");
    }

}
<小时/>
package org.pmesmeur.springboot.training.service.feature2;

public interface IMyFeature {

    void print();

}
<小时/>
package org.pmesmeur.springboot.training.service.feature2;

import org.springframework.stereotype.Component;


@Component
public class MyFeature implements IMyFeature {

    @Override
    public void print() {
        System.out.print("FooBar");
    }

}

如果我为我的类使用不同的名称MyFeature,我的问题就会消失!!!

我习惯使用Guice,这个框架没有这种问题/限制

It seems that the spring dependencies injection framework uses only the class-name instead of package-name + class-name in order to select its classes.

在“现实生活”中,我在一个更大的项目中遇到了这个问题,我强烈希望不必重命名我的类:任何人都可以帮助我吗?

One last point, I would prefer to avoid "tricks" such as using @Qualifier(value = "ABC") when injecting my classes: in my sample, there should be no ambiguity for finding the correct instance of MyFeature as they do not implement the same interface

最佳答案

简单地重新实现BeanNameGenerator会为通过名称声明/实例化的bean添加一个新问题

@Component("HelloWorld")
class MyComponent implements IComponent {
...
}

@Qualifier(value = "HelloWorld") IComponent component

我通过扩展 AnnotationBeanNameGenerator 并重新定义方法 buildDefaultBeanName() 解决了这个问题

static class BeanNameGeneratorIncludingPackageName extends AnnotationBeanNameGenerator {

    public BeanNameGeneratorIncludingPackageName() {
    }

    @Override
    public String buildDefaultBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
        return beanDefinition.getBeanClassName();
    }

}

关于SpringBoot : how to inject two classes having same name,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57140430/

相关文章:

java - 如何在属性文件中创建可以使用 Spring 的 @Value 注入(inject)的 Map<String, List<String>> 属性

java - 从基于 Spring 的 Java 应用程序创建单个可执行 JAR

java - 使用 Spring MVC 3.0 执行内联行编辑的最便捷方法

c# - Unity 配置和嵌套泛型类型

java - 如何在 JUnit 5 中使用 @RestTemplateClient?

amazon-web-services - 如何使用 AWS ECS 从 Parameter Store 获取数据库 key

java - 为什么 Spring Boot 中的验证消息没有被替换?

java - 使用 Jackson 将 Instant 序列化为 ISO8601 时强制毫秒数

java - 使用 @Produces 注释时出现不明确的依赖关系

c# - 需要当前 Request.Url 的类型的 Ninject 绑定(bind)