我正在我的 Spring 应用程序中实现多租户架构。
ConfigurationDataSource
类用于在应用程序启动时提供 DataSource
。下面是该类的详细实现:
ConfigurationDataSource
import com.example.hikaricp_demo.domain.TenantConfig;
import com.example.hikaricp_demo.repository.TenantConfigRepository;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Configuration
public class ConfigurationDataSource {
@Autowired
private TenantConfigRepository repository;
private List<TenantConfig> getListTenant(){
return repository.findAll();
}
TenantConfig tenantDefault() {
return repository.findByTenantId("tenantDefault");
}
@Bean
public DataSource dataSource() {
Map<Object, Object> resolvedDataSources = new HashMap<>();
List<TenantConfig> listTenant = getListTenant();
for (TenantConfig item : listTenant) {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName(item.getDriverClassName());
hikariConfig.setJdbcUrl(item.getUrl());
hikariConfig.setUsername(item.getUsername());
hikariConfig.setPassword(item.getPassword());
hikariConfig.setSchema(item.getSchema());
HikariDataSource dataSource = new HikariDataSource(hikariConfig);
resolvedDataSources.put(item.getTenantId(), dataSource);
}
AbstractRoutingDataSource dataSource = new MultiTenantDataSource();
dataSource.setDefaultTargetDataSource(tenantDefault());
dataSource.setTargetDataSources(resolvedDataSources);
dataSource.afterPropertiesSet();
return dataSource;
}
}
TenantConfigRepository
是一个 Spring Data JPA 存储库,它与数据库交互以获取租户配置。当我运行该应用程序时,出现以下错误:
Description:
The dependencies of some of the beans in the application context form a cycle:
entityManagerFactory defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]
┌─────┐
| dataSourceScriptDatabaseInitializer defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]
↑ ↓
| configurationDataSource (field private com.example.hikaricp_demo.repository.TenantConfigRepository com.example.hikaricp_demo.config.ConfigurationDataSource.repository)
↑ ↓
| tenantConfigRepository defined in com.example.hikaricp_demo.repository.TenantConfigRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration
↑ ↓
| jpaSharedEM_entityManagerFactory
└─────┘
我怀疑发生这种情况是因为:
dataSource bean 依赖于
TenantConfigRepository
(使用repository.findAll() 获取租户配置)。
TenantConfigRepository
也可能依赖于 DataSource
,从而创建循环依赖。
@Bean
@Lazy
public DataSource dataSource() {
//your code
}