Spring @Configuration 被忽略
Spring @Configuration is ignored
我将以下 dbunit 配置放在我所有测试 class 的父 class 中:
@Configuration
public class MyDbUnitConfiguration {
@Bean
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection() {
DatabaseConfigBean bean = new DatabaseConfigBean();
bean.setDatatypeFactory(new MySqlDataTypeFactory());
bean.setMetadataHandler(new MySqlMetadataHandler());
bean.setSkipOracleRecyclebinTables(true);
bean.setCaseSensitiveTableNames(false);
bean.setAllowEmptyFields(true);
String testDbName = getTestDbName();
LOG.debug("Test database name: " + testDbName);
DataSource dataSource = new DataSource();
dataSource.setUsername(USERNAME);
dataSource.setPassword(PASSWORD);
dataSource.setDriverClassName(JDBC_DRIVER);
String url = "jdbc:mysql://localhost:3306/" + testDbName;
dataSource.setUrl(url);
DatabaseDataSourceConnectionFactoryBean dbConnectionFactory = new DatabaseDataSourceConnectionFactoryBean(
dataSource);
dbConnectionFactory.setDatabaseConfig(bean);
return dbConnectionFactory;
}
}
但是,当我 运行 任何子测试 class.
时,此配置将被忽略(没有打印日志并且实际上没有设置属性)
当我在子测试上放置@Component注解时使用配置class,但是@Component只能使用一次,否则会打印异常:
org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'MyBaseTest' available: expected single matching bean but found 2:
FooTest,BarTest
因此我不能在每个子测试上都添加 @Component 注释 class。
如果将@Component 注释放在父测试上 class,则不会加载配置。
备注:
每个子测试 class 使用不同的数据库,其名称使用方法 getTestDbName()
检索。我需要此信息来配置我的数据库连接。
在每个子测试 class 是 运行 之前加载配置的正确方法是什么?这是 dbunit 将用来加载测试数据集的配置。
仔细阅读错误:
No qualifying bean of type 'MyBaseTest' available: expected single matching bean but found 2:
FooTest,BarTest
Spring 默认按类型自动装配,发现两个名为 FooTest
和 BarTest
的相同类型的 bean 有两种直接的方法可以修复它:
- 移除一颗豆子
- 使用
@Qualifier("FooTest")
注解和@Autowired
注解来定义哪个bean是候选使用。
注解@DbUnitConfiguration
救了我。
我能够通过 在它们上面添加以下注释 来配置每个子测试 class:
@Component
@DbUnitConfiguration(databaseConnection = { "myDbUnitConfigurationBean" })
public class FooTest extends MyBaseTest {
然后在每个子测试中放置一个配置 bean(并指定 bean 的名称)class:
@Bean(name = "myDbUnitConfigurationBean")
public DatabaseDataSourceConnectionFactoryBean getDbUnitDatabaseConnection() {
return createDbUnitDatabaseConnection(getTestDbName());
}
我还可以通过在父测试 class:
中定义方法 createDbUnitDatabaseConnection()
来分解一些代码
protected final DatabaseDataSourceConnectionFactoryBean createDbUnitDatabaseConnection(String testDbName) {
DatabaseConfigBean bean = new DatabaseConfigBean();
bean.setDatatypeFactory(new MySqlDataTypeFactory());
bean.setMetadataHandler(new MySqlMetadataHandler());
bean.setSkipOracleRecyclebinTables(true);
bean.setCaseSensitiveTableNames(false);
bean.setAllowEmptyFields(true);
LOG.debug("Test database name: " + testDbName);
DataSource dataSource = new DataSource();
dataSource.setUsername(USERNAME);
dataSource.setPassword(PASSWORD);
dataSource.setDriverClassName(JDBC_DRIVER);
String url = "jdbc:mysql://localhost:3306/" + testDbName;
dataSource.setUrl(url);
DatabaseDataSourceConnectionFactoryBean dbConnectionFactory = new DatabaseDataSourceConnectionFactoryBean(
dataSource);
dbConnectionFactory.setDatabaseConfig(bean);
return dbConnectionFactory;
}
现在我的 DbUnit 配置被每个子测试加载 class 这正是我想要的。
我将以下 dbunit 配置放在我所有测试 class 的父 class 中:
@Configuration
public class MyDbUnitConfiguration {
@Bean
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection() {
DatabaseConfigBean bean = new DatabaseConfigBean();
bean.setDatatypeFactory(new MySqlDataTypeFactory());
bean.setMetadataHandler(new MySqlMetadataHandler());
bean.setSkipOracleRecyclebinTables(true);
bean.setCaseSensitiveTableNames(false);
bean.setAllowEmptyFields(true);
String testDbName = getTestDbName();
LOG.debug("Test database name: " + testDbName);
DataSource dataSource = new DataSource();
dataSource.setUsername(USERNAME);
dataSource.setPassword(PASSWORD);
dataSource.setDriverClassName(JDBC_DRIVER);
String url = "jdbc:mysql://localhost:3306/" + testDbName;
dataSource.setUrl(url);
DatabaseDataSourceConnectionFactoryBean dbConnectionFactory = new DatabaseDataSourceConnectionFactoryBean(
dataSource);
dbConnectionFactory.setDatabaseConfig(bean);
return dbConnectionFactory;
}
}
但是,当我 运行 任何子测试 class.
时,此配置将被忽略(没有打印日志并且实际上没有设置属性)当我在子测试上放置@Component注解时使用配置class,但是@Component只能使用一次,否则会打印异常:
org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'MyBaseTest' available: expected single matching bean but found 2:
FooTest,BarTest
因此我不能在每个子测试上都添加 @Component 注释 class。
如果将@Component 注释放在父测试上 class,则不会加载配置。
备注:
每个子测试 class 使用不同的数据库,其名称使用方法 getTestDbName()
检索。我需要此信息来配置我的数据库连接。
在每个子测试 class 是 运行 之前加载配置的正确方法是什么?这是 dbunit 将用来加载测试数据集的配置。
仔细阅读错误:
No qualifying bean of type 'MyBaseTest' available: expected single matching bean but found 2: FooTest,BarTest
Spring 默认按类型自动装配,发现两个名为 FooTest
和 BarTest
的相同类型的 bean 有两种直接的方法可以修复它:
- 移除一颗豆子
- 使用
@Qualifier("FooTest")
注解和@Autowired
注解来定义哪个bean是候选使用。
注解@DbUnitConfiguration
救了我。
我能够通过 在它们上面添加以下注释 来配置每个子测试 class:
@Component
@DbUnitConfiguration(databaseConnection = { "myDbUnitConfigurationBean" })
public class FooTest extends MyBaseTest {
然后在每个子测试中放置一个配置 bean(并指定 bean 的名称)class:
@Bean(name = "myDbUnitConfigurationBean")
public DatabaseDataSourceConnectionFactoryBean getDbUnitDatabaseConnection() {
return createDbUnitDatabaseConnection(getTestDbName());
}
我还可以通过在父测试 class:
中定义方法createDbUnitDatabaseConnection()
来分解一些代码
protected final DatabaseDataSourceConnectionFactoryBean createDbUnitDatabaseConnection(String testDbName) {
DatabaseConfigBean bean = new DatabaseConfigBean();
bean.setDatatypeFactory(new MySqlDataTypeFactory());
bean.setMetadataHandler(new MySqlMetadataHandler());
bean.setSkipOracleRecyclebinTables(true);
bean.setCaseSensitiveTableNames(false);
bean.setAllowEmptyFields(true);
LOG.debug("Test database name: " + testDbName);
DataSource dataSource = new DataSource();
dataSource.setUsername(USERNAME);
dataSource.setPassword(PASSWORD);
dataSource.setDriverClassName(JDBC_DRIVER);
String url = "jdbc:mysql://localhost:3306/" + testDbName;
dataSource.setUrl(url);
DatabaseDataSourceConnectionFactoryBean dbConnectionFactory = new DatabaseDataSourceConnectionFactoryBean(
dataSource);
dbConnectionFactory.setDatabaseConfig(bean);
return dbConnectionFactory;
}
现在我的 DbUnit 配置被每个子测试加载 class 这正是我想要的。