首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SpringBoot:如何注入两个同名类

SpringBoot:如何注入两个同名类
EN

Stack Overflow用户
提问于 2019-07-22 06:44:59
回答 4查看 4.7K关注 0票数 5

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

需要在应用程序中注入这两个类;不幸的是,我得到了以下错误消息:

代码语言:javascript
复制
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]

我的问题可以通过以下样本复制:

代码语言:javascript
复制
@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;
    }
    ...
代码语言:javascript
复制
package org.pmesmeur.springboot.training.service.feature1;

public interface IMyFeature {

    void print();

}
代码语言:javascript
复制
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");
    }

}
代码语言:javascript
复制
package org.pmesmeur.springboot.training.service.feature2;

public interface IMyFeature {

    void print();

}
代码语言:javascript
复制
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,并且这个框架没有这样的问题/限制。

看来,spring依赖项注入框架只使用类名而不是包名+类名来选择其类。

在“现实生活”中,我遇到了一个大得多的项目的问题,我强烈希望不用重命名我的课程:有人能帮我吗?

最后一点,我倾向于避免使用“技巧”,例如在注入类时使用@Qualifier(value = "ABC"):在我的示例中,找出MyFeature的正确实例不应含糊不清,因为它们没有实现相同的接口。

EN

回答 4

Stack Overflow用户

发布于 2019-08-07 14:28:53

只需重新实现BeanNameGenerator,就会为名称声明/实例化的bean增加一个新问题。

代码语言:javascript
复制
@Component("HelloWorld")
class MyComponent implements IComponent {
...
}

@Qualifier(value = "HelloWorld") IComponent component

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

代码语言:javascript
复制
static class BeanNameGeneratorIncludingPackageName extends AnnotationBeanNameGenerator {

    public BeanNameGeneratorIncludingPackageName() {
    }

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

}
票数 2
EN

Stack Overflow用户

发布于 2019-07-22 07:00:08

您可以为每个组件指定一个值,例如@Component(value="someBean"),然后将其注入@Qualifier

代码语言:javascript
复制
@Autowired
public SomeService(@Qualifier("someBean") Some s){
   //....
}
票数 0
EN

Stack Overflow用户

发布于 2019-07-22 07:07:35

你可以这样做;

包内a

代码语言:javascript
复制
public class MyFeature implements IMyFeature {

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

包内b

代码语言:javascript
复制
public class MyFeature implements IMyFeature {

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

在某些配置类中;

代码语言:javascript
复制
@Configuration
public class Configuration {

    @Bean
    public a.MyFeature f1() {
        return new a.MyFeature();
    }

    @Bean
    public b.MyFeature f2() {
        return new b.MyFeature();
    }
}

然后,您可以自动使用名称f1f2,这是它们各自的bean构造函数方法的名称。

您可以使用@Component("f1") & @Component("f2")做类似的事情

即使在不同的包中实现了不同的接口,相同的bean名称也会导致这个问题,您必须使用某种自定义命名来区分。与使用上面的解决方案相比,使用一些自定义弹簧逻辑就太难看了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57140430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档