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 默认按类型自动装配,发现两个名为 FooTestBarTest 的相同类型的 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 这正是我想要的。