我在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此豆子,则有效!