无法覆盖 bean @Primary Spring 注释



我在dispatcher-servlet.xml中定义了一个豆子,如下所示:

<!-- 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 注释进行配置)中,我想覆盖这个 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。这是记录的输出:

[信息] 用 不同的定义:替换 [根豆:类 [空]; 范围=; 摘要=假;lazyInit=false;自动连线模式=3;依赖检查=0; autowireCandidate = true;主要=真;工厂豆名=配置; 工厂方法名称=数据源;initMethodName=null; 销毁方法名称=(推断);定义于 ...与 [通用豆:类 [org.springframework.jdbc.datasource.DriverManagerDataSource];范围=; 摘要=假;lazyInit=false;自动连线模式=0;依赖检查=0; autowireCandidate = true;主要=假;工厂豆名=空; 工厂方法名称=空;initMethodName=null;销毁方法名称=空; 在 URL [dispatcher-servlet.xml]] 中定义

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

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

但是,作为您问题的答案,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;

但我仍然不确定它是否有效。

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

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

只要放一个包含所有带注释的类的包而不是your.base.package,它们应该被 Spring 拾取,因为我仍然不相信 Spring 会拾取它们。

根据@Primary Javadoc XML配置优先于基于Java的配置:

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

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

只是为了在测试Bean重新定义@Configuration类中使用不同的方法名称(例如,向其添加">2"或">ForTest"后缀):

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

或在 @Bean(name="数据源2")中使用"name"属性。 如果您按类型@Autowired此豆子,则有效!

最新更新