SpringBoot创建DynamicDataSource报错:请求的Bean正创建中,是否存在无法解决的循环依赖?
Hey there, that "requested bean is currently in creation" error is a classic circular dependency issue—let’s break down why this might be happening and how to fix it with your current setup.
Possible Root Causes
First, let’s look at what could be triggering this:
- Your
dynamicDataSourcebean might be indirectly referenced by another component that depends on it (like a transaction manager, MyBatisSqlSessionFactory, or a repository using the dynamic data source), creating a loop. - Spring’s auto-configuration might be interfering—if
DataSourceAutoConfigurationtries to create a default data source that ends up depending on your dynamic one, that can cause a cycle. - There could be an implicit self-dependency in your dynamic data source logic (e.g., initializing something in the bean’s constructor that requires the fully created
dynamicDataSourceitself).
Step-by-Step Solutions
1. Break the Cycle with @Lazy Injection
The simplest fix is often to use @Lazy to delay the initialization of dependent beans. Try adding it to the data source injections in your dynamicDataSource bean:
@Bean(name = "dynamicDataSource") public DataSource dataSource( @Lazy @Qualifier("masterDataSource") DataSource masterDataSource, @Lazy @Qualifier("slaveDataSource") DataSource slaveDataSource ) { // Your dynamic data source routing logic here }
@Lazy tells Spring to create a proxy instead of initializing the bean immediately, which breaks the circular reference chain.
2. Explicitly Define Bean Creation Order with @DependsOn
While Spring usually handles dependency order automatically, you can enforce that masterDataSource and slaveDataSource are fully created before dynamicDataSource:
@Bean(name = "dynamicDataSource") @DependsOn({"masterDataSource", "slaveDataSource"}) public DataSource dataSource( @Qualifier("masterDataSource") DataSource masterDataSource, @Qualifier("slaveDataSource") DataSource slaveDataSource ) { // Your logic here }
This ensures the two slave/master beans are ready before the dynamic one starts initializing.
3. Exclude Conflicting Auto-Configuration
If Spring’s default DataSourceAutoConfiguration is clashing with your custom setup, exclude it from your application class to prevent it from creating a default data source that might form a cycle:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) public class YourSpringBootApplication { public static void main(String[] args) { SpringApplication.run(YourSpringBootApplication.class, args); } }
Note: If you do this, you’ll need to manually configure related beans like PlatformTransactionManager or SqlSessionFactory (if using MyBatis) to use your dynamicDataSource.
4. Check Your Dynamic Data Source Implementation
If you’re using AbstractRoutingDataSource (the common base class for dynamic data sources), make sure you’re not triggering data source operations during initialization. Avoid calling methods that require a connection in the constructor—use @PostConstruct instead for any setup logic:
@Bean(name = "dynamicDataSource") public DataSource dataSource( @Qualifier("masterDataSource") DataSource masterDataSource, @Qualifier("slaveDataSource") DataSource slaveDataSource ) { AbstractRoutingDataSource dynamicDS = new AbstractRoutingDataSource() { @Override protected Object determineCurrentLookupKey() { // Your routing logic here } }; // Set target data sources dynamicDS.setTargetDataSources(Map.of("master", masterDataSource, "slave", slaveDataSource)); dynamicDS.setDefaultTargetDataSource(masterDataSource); // Use @PostConstruct if you need to run initialization logic that uses the data source return dynamicDS; }
Quick Check
Double-check if any other beans (like transaction managers, JPA EntityManagerFactory, or DAOs) are referencing dynamicDataSource while that bean is still being created. If so, adding @Lazy to those references can also resolve the cycle.
内容的提问来源于stack exchange,提问作者ChangQi

