【问题标题】:How it works together these 2 Spring Java configuration classes?这两个 Spring Java 配置类如何协同工作?
【发布时间】:2014-11-12 10:22:49
【问题描述】:

我正在学习 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:AccountRepositoryRestaurantRepository RewardRepository

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

我可以说 RewardNetwork已声明的 bean 并且 RewardNetworkImpl 是此 bean 的当前实现吗?

所有 3 个 bean(AccountRepositoryRestaurantRepositoryRewardRepository)都依赖于另一个 bean dataSource,因为你可以看到在前面的代码sn -p,被声明为@Autowired

@Autowired
DataSource dataSource;

这个 bean 没有在这个配置类中声明,因为它会根据环境(测试、开发、生产)而变化。

所以,在我的例子中,它被声明到单元测试文件夹 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

【问题讨论】:

    标签: java spring dependency-injection applicationcontext


    【解决方案1】:

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

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

    【讨论】:

    • mm 好的,现在我明白使用 Import 注释我不必导入 bean。在这种情况下,TestInfrastructureConfig 仅适用于我在生产环境中没有的测试环境。你的意思是我可以使用 Import 注解来处理这些情况吗?现在我在测试环境中,它会加载 TestInfrastructureConfig 但是当我在生产环境中时,我将没有 TestInfrastructureConfig 而是我将拥有 ProductionInfrastructureConfig 并且这个类会自动使用?这是 Autowired 注释选择的含义吗? Tnx
    • Autowired 意味着 Spring 会在某处找到一些匹配的 bean。使用它的类,无论是配置类还是其他服务bean,都不需要知道Spring从哪里得到它;它不必提供所有自己的依赖项。您的测试用例需要包含其他一些不相关的来源,这些来源提供DataSource
    猜你喜欢
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 2018-04-05
    • 2012-01-18
    • 2013-05-28
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    相关资源
    最近更新 更多