Java 尽管使用了@Primary,但两个具有相同名称的 bean 仍会导致 ConflictingBeanDefinitionException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24066425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 09:58:39  来源:igfitidea点击:

Two beans with the same name results in ConflictingBeanDefinitionException despite using @Primary

javaspringinversion-of-controlspring-ioc

提问by fracz

I have an application initializer class that is used to insert application specific data to database.

我有一个应用程序初始值设定项类,用于将特定于应用程序的数据插入数据库。

@Component("applicationInitializer")
public class ApplicationInitializer {
    @PostConstruct
    public void init(){
        // some clever code here
    }
}

There is also DevApplicationInitializerclass that is used to initialize database with some sample data on developer machine (this class is excluded when deploying production code).

还有一个DevApplicationInitializer类用于在开发人员机器上使用一些示例数据初始化数据库(部署生产代码时排除该类)。

@Component("applicationInitializer")
@Primary
public class DevApplicationInitializer extends ApplicationInitializer {
    @PostConstruct
    @Override
    public void init(){
        super.init();
        // even more clever code here
    }
}

Until I have given a name for the beans (only the @Componentannotations) - everything worked fine - when DevApplicationInitializerwas available, it was instantiated instead of ApplicationInitializer. When I gave them an applicationInitializername, the exception is being thrown:

直到我为 bean 命名(只有@Component注释) - 一切正常 - 当DevApplicationInitializer可用时,它被实例化而不是ApplicationInitializer. 当我给他们一个applicationInitializer名字时,抛出异常:

org.springframework.context.annotation.ConflictingBeanDefinitionException: 
Annotation-specified bean name 'applicationInitializer' for bean class
[com.example.DevApplicationInitializer] conflicts with existing, non-compatible 
bean definition of same name and class [com.example.ApplicationInitializer]

Why the @Primaryannotation is not respected when beans have name? I need them to have one, because I ensure in other place that the initializer has been instantiated with @DependsOn("applicationInitializer")annotation.

@Primary当 bean 有名称时,为什么不尊重注释?我需要他们拥有一个,因为我确保在其他地方初始化器已使用@DependsOn("applicationInitializer")注释实例化。

采纳答案by Sotirios Delimanolis

@Primaryhas no relation to bean names. The javadoc states

@Primary与 bean 名称无关。javadoc 指出

Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency.

指示当多个候选者有资格自动装配单值依赖项时,应该优先考虑一个 bean。

This only applies to a context containing two beans of some type Awhere a bean of type Brequires an Ato be injected. The A bean annotated with @Primarywill have priority.

这仅适用于包含某种类型的两个 bean 的上下文,A其中一个类型的 beanB需要A被注入。带有注释的 A bean@Primary将具有优先权。

Bean ids/names for a given type must be unique. (Bean definitions with the same name can overwrite each other for the same bean type. For example, this would happen if you component scanned a class annotated with @Componentbut also provided a @Beanmethod for that same type.)

给定类型的 Bean id/名称必须是唯一的。(对于相同的 bean 类型,具有相同名称的 Bean 定义可以相互覆盖。例如,如果您的组件扫描了一个注释的类,@Component但也@Bean为该相同类型提供了一个方法,就会发生这种情况。)