Johniya Blog
首页 博客 社区 问答 开发者 约米云盘 注册
spring下的异步调用-方法提前返回
默凌 2024-07-04 19:00:22 北京 spring java 开发

spring服务端的实际开发中,经常会遇到需要提前返回响应,然后服务器在继续处理逻辑的情况。

比如,当一个逻辑处理时需要大量资源,并且用户不需要感知结果时。
或者,当用户操作一个动作时,服务器需要连带做一些其他额外的内部逻辑,是不需要用户感知的。

这时候就需要异步调用,即在当前http线程之外单独开一个线程,完成额外的逻辑,本线程完成处理逻辑后直接返回响应。

在spring体系下,提供了一个@Async注解。

public Response regitser(User user) {
	...
	// 新增用户
	userService.addUser(user)
	...
	// 通知相关人员有用户注册
	notifyRegister(user)
	...
}

这个场景下,用户注册后,需要通知公司相关人员,已有用户注册,这个逻辑是不需要改请求的用户感知的,且可能需要通过其他通讯方式通知到相关人员,所以资源消耗较大,且花费时间较长。
所以对于notifyRegister()方法是有必要单独开一个线程的。

@Async
public void notifyRegister(User user) {
	...
}

所以在该方法上添加@Async注解,并且在configuration类或Application类增加@EnableAsync注解

以上使用的是spring提供的默认线程池

但是如果这种情况线程较多,且类型不同,希望多个线程池互相不干扰。

则可以配置不同的线程池,然后在使用@Async注解时指定线程池。

@Configuration
@EnableAsync
public class AsyncConfiguration {

    @Bean("aaaExecutor")
    public Executor aaaExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(Integer.MAX_VALUE);
        executor.initialize();
        return executor;
    }

    @Bean("bbbExecutor")
    public Executor bbbExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(Integer.MAX_VALUE);
        executor.initialize();
        return executor;
    }
}
@Async("bbbExecutor")
public void notifyRegister(User user) {
	...
}

上面定义配置了两个不同的线程池,然后在不同场景下,指定不同的线程池。

云服务器 免费试用 一键搭建个人网站 现在购买,领取免费顶级域名 糯米云
5
1
0
21
评论 0
@Johniya.top