Springboot Async 引起的循环依赖

Springboot_Async_circular_dependency_solution

Springboot Async 引起的循环依赖

问题

今天遇到一个问题,本地打包没问题,运行也没问题,但是上服务器部署的时候,报错 错误:

org.springframework.beans.factory.BeanCurrentlyInCreationException:
 Error creating bean with name 'asyncConfigServiceImpl':
 Bean with name 'asyncConfigServiceImpl' has been injected into other beans [componentConfigVersionServiceImpl] 
 in its raw version as part of a circular reference, 
 but has eventually been wrapped.
  This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.

然后我的大致代码是这样的

@Service
@Slf4j
public class A {
    @Autowired
    private B b;
}
@Service
@Slf4j
public class B {
    @Autowired
    private A a;
    @Override
    @Async
    public void asyncUploadFileToBoss( ) {
        log.info("async start upload file ");
        a.uploadFileToBoss();
        log.info("async end upload file ");
    }
}

在不加 @Async 注解的时候,是没问题的,但是加了这个注解就会报错,原因:涉及到了springboot的 依赖加载 的顺序问题,想知道具体原因大家可以搜一下看下,这里主要是说一下解决方案

很简单在

@Service
@Slf4j
public class A {
	//这里加一个注解     @Lazy 就解决了
    @Autowired
    @Lazy
    private B b;
}
### SpringBoot 中 MyBatis 结合线程池实现循环插入数据库的并发处理 在 Spring Boot 项目中,通过结合 MyBatis 和线程池可以高效地完成大量数据的循环插入操作。以下是具体实现方法: #### 配置线程池 首先,在 `application.properties` 或 `application.yml` 文件中定义线程池的相关参数[^4]: ```properties # 异步线程配置 async.executor.thread.core_pool_size=30 # 核心线程数 async.executor.thread.max_pool_size=50 # 最大线程数 async.executor.thread.queue_capacity=100 # 队列容量 async.executor.thread.keep_alive_seconds=60 # 空闲线程存活时间 async.executor.thread.name.prefix=importDB- # 线程名前缀 ``` 接着,在 Spring Boot 的配置类中创建并注册线程池 Bean[^3]: ```java @Configuration public class ThreadPoolConfig { @Bean(name = "taskExecutor") public ThreadPoolTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(30); // 核心线程数 executor.setMaxPoolSize(50); // 最大线程数 executor.setQueueCapacity(100); // 队列容量 executor.setKeepAliveSeconds(60); // 空闲线程存活时间 executor.setThreadNamePrefix("importDB-");// 线程名前缀 executor.initialize(); return executor; } } ``` #### 实现服务层逻辑 在 Service 层中编写业务逻辑,使用线程池提交任务来执行循环插入操作[^2]: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Autowired @Qualifier("taskExecutor") private ThreadPoolTaskExecutor threadPoolTaskExecutor; /** * 批量插入用户数据 */ @Override public void batchInsertUsers(List<User> userList) { int batchSize = 1000; // 每次提交的任务数量 List<List<User>> partitionedLists = Lists.partition(userList, batchSize); for (List<User> subList : partitionedLists) { threadPoolTaskExecutor.submit(() -> { try { userMapper.batchInsert(subList); } catch (Exception e) { log.error("批量插入失败", e); } }); } // 关闭线程池等待所有任务结束 threadPoolTaskExecutor.shutdown(); try { while (!threadPoolTaskExecutor.awaitTermination(60, TimeUnit.SECONDS)) { log.info("仍有未完成的任务..."); } } catch (InterruptedException e) { log.error("线程中断异常", e); } log.info("所有任务已完成!"); } } ``` #### Mapper 接口与 XML 配置 为了支持批量插入,可以在 MyBatis 的 Mapper 接口中定义对应的方法,并在对应的 XML 文件中提供 SQL 支持。 ##### Mapper 接口 ```java @Mapper public interface UserMapper { void batchInsert(@Param("users") List<User> users); } ``` ##### XML 配置文件 ```xml <insert id="batchInsert"> INSERT INTO user (id, name, age) VALUES <foreach collection="users" item="user" separator=","> (#{user.id}, #{user.name}, #{user.age}) </foreach> </insert> ``` 以上代码实现了基于线程池的批量插入功能,能够显著提升大规模数据插入的效率[^1]。 --- ### 注意事项 1. **事务管理**:如果需要保证数据一致性,建议在线程池外部开启事务控制。 2. **资源释放**:确保线程池关闭时不会影响其他依赖它的组件运行。 3. **性能调优**:根据实际硬件环境调整线程池的核心线程数、最大线程数以及队列容量等参数。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值