4

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

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

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

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

直到我为 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]

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

4

1 回答 1

4

@Primary与bean名称无关。javadoc 状态

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

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

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

于 2014-06-05T18:29:37.413 回答