首页 > 其他分享 >使用SpringBoot异步方法优化报销单查询接口,提高接口响应速度

使用SpringBoot异步方法优化报销单查询接口,提高接口响应速度

时间:2023-03-31 14:35:03浏览次数:48  
标签:异步 SpringBoot 方法 接口 响应速度 线程 import threadPoolTaskExecutor CompletableFuture

合理使用异步方法可以提高接口性能。异步方法适用于逻辑与逻辑之间可以相互分割互不影响的业务中。

SpringBoot 支持异步方法调用。具体用法:

  1. 在启动类添加@EnableAsync注解,声明开启异步方法
  2. 在异步方法添加@Async注解,被@Async注解修改的方法由SpringBoot默认线程池(SimpleAsyncTaskExecutor)执行。

注意:

  • 异步方法可以不使用默认线程池 SimpleAsyncTaskExecutor,可以自定义线程池执行。

  • 如果直接将需要异步操作的方法写到业务类中,业务类直接调用,异步方法会失效。因为@Async的调用涉及到动态代理,业务类直接调用的话,则执行逻辑不会走到代理类。因此需要将 @Async 注解的方法单独拿出来封装到一个类中,再将这个类注入到业务类中,业务类通过这个类来调用异步方法

  • 如果要获取异步方法的返回值,需要使用Future类及其子类来接收异步方法返回值,推荐使用 CompletableFuture

自定义线程池执行异步方法

1.新增线程池配置类

package com.study.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池配置类
 */
@Configuration
public class TaskThreadPoolConfig {

    private static final Logger logger = LoggerFactory.getLogger(TaskThreadPoolConfig.class);

    @Value("${task.execution.pool.core-size}")
    private int corePoolSize;
    @Value("${task.execution.pool.max-size}")
    private int maxPoolSize;
    @Value("${task.execution.pool.queue-capacity}")
    private int queueCapacity;
    @Value("${task.execution.pool.keep-alive}")
    private int keepAliveSeconds;
    @Value("${task.execution.pool.name-prefix}")
    private String namePrefix;


    @Bean("executeService")
    public Executor asyncServiceExecutor() {
        logger.info("start asyncServiceExecutor");
        //ThreadPoolTaskExecutor是Spring提供的线程池,底层也是使用JDK的ThreadPoolExecutor实现的。
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        //配置核心线程数
        threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
        //配置最大线程数
        threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
        //配置队列大小
        threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
        //当线程数大于核心线程数,终止多余线程等待新任务的最长时间
        threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
        //配置线程池中的线程的名称前缀
        threadPoolTaskExecutor.setThreadNamePrefix(namePrefix);
        //配置线程的饱和策略。CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }
}

2.在Async注解指定使用的线程池

@Async("executeService")

使用CompletableFuture获取异步方法返回值

比如:在业务类要异步(method1和method2)获取信息组合到infoMap集合并返回数据。

// 数据1 
CompletableFuture<String> data1 = this.testService.method1();

// 数据2
CompletableFuture<String> data2 = this.testService.method2();

//allOf() 方法会等到所有的 CompletableFuture 都运行完成之后再返回.调用 join() 可以让程序等所有CompletableFuture都运行完了之后再继续执行。
CompletableFuture.allOf(data1, data2).join();
        
infoMap.put("data1", data1.get());
infoMap.put("data2", data2.get());

参考资料

标签:异步,SpringBoot,方法,接口,响应速度,线程,import,threadPoolTaskExecutor,CompletableFuture
From: https://www.cnblogs.com/1963942081zzx/p/17276159.html

相关文章

  • 接口自动化之测试数据动态生成并替换
    一、测试数据1.随机库random查看内置random方法,该方法自行学习,不再介绍。showprint([namefornameindir(random)ifcallable(getattr(random,name))])['Random','SystemRandom','_Sequence','_Set','_accumulate','_acos......
  • node express自动生成swagger(openApi)接口文档
    先看效果图:   实现步骤:1.安装所需的包npminstallswagger-jsdocswagger-ui-express2.新建文件swagger.js//swagger在线网站:https://editor.swagger.io/#constswaggerJSDoc=require('swagger-jsdoc')constswaggerUi=require('swagger-ui-express')......
  • 使用PHP调用OpenAI ChatGPT API接口
    本文介绍如何使用PHP调用OpenAI的文本完成模型ChatGPT的API接口,同时也包括图片生成模型DALL·E接口的调用。 一、SDK实现OpenAI的PHPSDK实现如下,其中ChatGPT使用的模型为gpt-3.5-turbo,如果已经有ChatGPTPlus,并申请到GPT-4的API权限,可以改为GPT-4的模型。classclass_openai......
  • SpringBoot中如何动态加载类到容器
    任何业务脱离场景无任何实际意义。场景:1,实现了多种存储方式,redis和本地内存或者其它,但是你希望根据注解配置只加载一种类到容器。2,经典场景:mybatis将接口的代理类动态加载到容器。分类:静态加载:1,springboot中会扫描同包路径下的(@configuration@Service@Component)标记了上述......
  • SpringBoot2.7集成Swagger3
    1、引入pom坐标<!--swagger--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>3.0.0</version></dependency><dependency><groupId&......
  • 网页接口偶发性502的问题
    现象:网页接口一直偶发性502,概率大概20%左右 排查过程:架构是用户->WAF->lvs->NGINX->后端 1、尝试减少接口请求,依然会502,可知和接口服务能力无关。2、WAF侧,更换服务IP,依然不行,可知不是WAF某个节点网络有问题。3、Nginx侧,查看日志,并未发现502日志,可知502的请求没到nginx,怀......
  • C#: IDisposable接口
    在C#中,IDisposable接口用于释放非托管资源。非托管资源是指由操作系统或其他非托管代码创建的资源,如文件句柄、数据库连接、网络连接等。这些资源不受垃圾回收器的管理,因......
  • springboot注册Servlet、Filter、Listener的方式
    方式一:注解@WebServlet@WebFilter@WebListener在实现类上使用该注解即可一键注册方式二:配置类在@Configuration标识的配置类中通过RegistrationBean进行注册@Beanp......
  • 自定义注解方式接口防刷实现
    原作前言本文为描述通过Interceptor以及Redis实现接口访问防刷Demo这里会通过逐步找问题,逐步去完善的形式展示原理通过ip地址+uri拼接用以作为访问者访问接口区......
  • SpringBoot 项目使用 Sa-Token 完成登录认证
    一、设计思路对于一些登录之后才能访问的接口(例如:查询我的账号资料),我们通常的做法是增加一层接口校验:如果校验通过,则:正常返回数据。如果校验未通过,则:抛出异常,告知其需......