它如何与这两个Spring Java配置类一起工作?

时间:2014-11-12 10:22:50

标签: java spring dependency-injection applicationcontext

我正在攻读Spring Core认证,并且我对使用Java配置方式的bean配置相关的练习表示怀疑。

所以我有以下 RewardsConfig 类来配置我的bean(这个类进入应用程序文件夹 src / main / java ):

package config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import rewards.RewardNetwork;
import rewards.internal.RewardNetworkImpl;
import rewards.internal.account.AccountRepository;
import rewards.internal.account.JdbcAccountRepository;
import rewards.internal.restaurant.JdbcRestaurantRepository;
import rewards.internal.restaurant.RestaurantRepository;
import rewards.internal.reward.JdbcRewardRepository;
import rewards.internal.reward.RewardRepository;

@Configuration
public class RewardsConfig {

    @Autowired
    DataSource dataSource;

    @Bean
    public RewardNetwork rewardNetwork(){
        return new RewardNetworkImpl(accountRepository(), restaurantRepository(), rewardRepository());
    }

    @Bean
    public AccountRepository accountRepository(){
        JdbcAccountRepository repository = new JdbcAccountRepository();
        repository.setDataSource(dataSource);
        return repository;
    }

    @Bean
    public RestaurantRepository restaurantRepository(){
        JdbcRestaurantRepository repository = new JdbcRestaurantRepository();
        repository.setDataSource(dataSource);
        return repository;
    }

    @Bean
    public RewardRepository rewardRepository(){
        JdbcRewardRepository repository = new JdbcRewardRepository();
        repository.setDataSource(dataSource);
        return repository;
    }

}

正如您所看到的,我声明了4个用于创建4个bean的方法,并指定了这些bean之间的依赖关系。

所以我有一个 RewardNetwork bean,由 RewardNetworkImpl 类实现,该类依赖于以下3个bean: AccountRepository RestaurantRepository RewardRepository

对Java配置的正确解释是Spring吗?

我可以说 RewardNetwork 声明的bean RewardNetworkImpl 是该bean的当前实现吗?

所有3beans( AccountRepository RestaurantRepository RewardRepository )都依赖于另一个bean dataSource ,就像你一样可以在前面的代码片段中看到,声明为 @Autowired

@Autowired
DataSource dataSource;

此bean未在此配置类中声明,因为它根据环境(test,developt,production)而变化。

所以,在我的情况下,它被声明到单元测试文件夹 src / test / java

package rewards;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;

@Configuration
public class TestInfrastructureConfig {

    /**
     * Creates an in-memory "rewards" database populated 
     * with test data for fast testing
     */
    @Bean
    public DataSource dataSource(){
        return
            (new EmbeddedDatabaseBuilder())
            .addScript("classpath:rewards/testdb/schema.sql")
            .addScript("classpath:rewards/testdb/test-data.sql")
            .build();
    }   
}

因此 dataSource bean定义了一个仅对测试环境有效的数据源(在执行单元测试时使用)。

现在我的疑问是:我有2个不同的配置类, dataSource bean没有定义到包含使用它的3个bean的 RewardsConfig 配置类。为什么我不能使用 @Import 注释将其用于 RewardsConfig

喜欢它的东西:

@Import(TestInfrastructureConfig.class)

它是如何工作的?

TNX

1 个答案:

答案 0 :(得分:1)

您不必导入bean以使其可用于自动装配。 @Import用于添加额外的配置类。

真的不想硬导入测试配置类,因为那时你的生产代码指的是只测试代码(在这种情况下,总是激活它) 。相反,将您的配置类更像是一个抽象类:声明自动装配的bean,但不要担心它们是如何实现的。下游(运行时)配置将提供它们,您不需要知道如何。也许您正在提供内存中的H2用于测试和使用Spring Cloud Connectors进行实际运行,这并不重要。