java - 这两个 Spring Java 配置类如何协同工作?

标签 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 之间发生的依赖关系。

所以我有一个由 RewardNetworkImpl 类实现的 RewardNetwork bean,它依赖于以下 3 个 bean:AccountRepositoryRestaurantRepository RewardRepository

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

例如,我可以说 RewardNetwork声明的 beanRewardNetworkImpl 是该 bean 的当前实现吗?

所有 3bean(AccountRepositoryRestaurantRepositoryRewardRepository)都依赖于另一个 bean dataSource,当您在前面的代码片段中可以看到,声明为@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

最佳答案

您不必导入 bean 即可使它们可用于 Autowiring 。 @Import 用于添加额外的配置类。

真的不想硬导入测试配置类,因为这样您的生产代码将引用仅测试代码(并且在这种情况下,始终激活它)。相反,您的配置类更像是一个抽象类:声明 Autowiring 的 bean,但不用担心它们如何到达那里。下游(运行时)配置将提供它们,您不需要知道如何提供。也许您正在提供内存中的 H2 用于测试并使用 Spring Cloud Connector 进行实际运行,但这并不重要。

关于java - 这两个 Spring Java 配置类如何协同工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26884558/

相关文章:

jsf - 在另一个 View 范围 bean 中注入(inject)一个 View 范围 bean 会导致它被重新创建

java - 为什么gradle创建的jar文件中没有.class文件?

java - 为什么我必须在 spring data jpa 中将 @Modifying 与 @Transactional 一起使用?

spring - 如何使用 spring cloud config server 和 spring cloud bus 和 rabbit mq 更新配置?

Spring Java 配置 : import properties file

security - Grails Spring Security 插件 - 与用户域一对一关联

java - 依赖注入(inject)java

scala - 将依赖项注入(inject)集群持久 Akka Actor 的正确方法?

java - 更改 Camel TestSupport 中的 log4j 设置

Java反射: Invoke function in a inner static class