我正在学习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:AccountRepository、RestaurantRepository 和 RewardRepository。
Java配置的正确解释是Spring吗?
例如,我可以说 RewardNetwork 是声明的 bean 而 RewardNetworkImpl 是该 bean 的当前实现吗?
所有 3bean(AccountRepository、RestaurantRepository 和 RewardRepository)都依赖于另一个 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/