但是不能覆盖bean @Primary Spring注释

时间:2017-03-24 17:02:03

标签: java spring spring-mvc integration-testing

我在dispatcher-servlet.xml中定义了一个像这样的bean:

<!-- Datasource configuration -->
<beans:bean id="dataSource" name="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">      
   <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
   <beans:property name="url" value="" />
   <beans:property name="username" value="" />
   <beans:property name="password" value="" /> 
</beans:bean>

在另一个config.class(这次使用Java Annotation进行配置)我想覆盖这个bean。这是新bean的定义:

@ImportResource(dispatcher-servlet.xml)

    @Bean
    @Primary
    public EmbeddedDatabase dataSource() {
        EmbeddedDatabaseBuilder databaseBuilder = new EmbeddedDatabaseBuilder();
        databaseBuilder.setName("testDB");
        databaseBuilder.setType(EmbeddedDatabaseType.H2);

        return databaseBuilder.build();
    }

在测试中我写道:

@ContextConfiguration(classes = config.class)
@WebAppConfiguration
// Test

意外的结果是Spring选择的具有id dataSource的bean是在xml文件中定义的bean。这是记录的输出:

  

[info]覆盖bean&#39; dataSource&#39;的bean定义用一个   不同的定义:替换[Root bean:class [null];范围=;   抽象= FALSE; lazyInit = FALSE; autowireMode = 3; dependencyCheck = 0;   autowireCandidate = TRUE;初级= TRUE; factoryBeanName =配置;   factoryMethodName =数据源; initMethodName = NULL;   destroyMethodName =(推断);在...中定义[Generic bean:class   [org.springframework.jdbc.datasource.DriverManagerDataSource];范围=;   抽象= FALSE; lazyInit = FALSE; autowireMode = 0; dependencyCheck = 0;   autowireCandidate = TRUE;初级= FALSE; factoryBeanName = NULL;   factoryMethodName = NULL; initMethodName = NULL; destroyMethodName = NULL;   在URL [dispatcher-servlet.xml]]

中定义


似乎@Primary注释被忽略。
为什么?解决方案是什么?

2 个答案:

答案 0 :(得分:2)

我不确定混合使用不同的配置类型是个好主意。如果我要阅读那种配置,我可能会挣扎,并且相信我,我实际上做了很多。

但是,作为您的问题的答案,XML优先于注释。因此,尝试以XML格式声明bean,或仅在应用程序中使用注释。

您可以尝试使用@Qualifier注释。也许是这样的:

@Bean
@Qualifier("my_qualifier")
public EmbeddedDatabase dataSource() {
    EmbeddedDatabaseBuilder databaseBuilder = new EmbeddedDatabaseBuilder();
    databaseBuilder.setName("testDB");
    databaseBuilder.setType(EmbeddedDatabaseType.H2);

    return databaseBuilder.build();
}

使用以下方法注入:

@Autowired
@Qualifier("my_qualifier")
EmbeddedDatabase database;

但我仍然不确定它是否会起作用。

P.S。如果尚未设置自动注释扫描,则应将其添加到XML中。从您提到的评论来看,它已经过时,但事实并非如此。

<context:component-scan base-package="your.base.package" />

只需放一个包含所有注释类而不是your.base.package的包,它们应该被Spring选中,因为我仍然不相信Spring正在接受它们。

答案 1 :(得分:1)

根据@Primary Javadoc XML配置在基于Java的配置之前具有优先权:

  

如果通过声明@Primary - 注释类   XML,@Primary注释元数据被忽略,并且   <bean primary="true|false"/>会得到尊重。

因此,不会覆盖来自XML配置的bean。