• springboot实现异步调用


    介绍

    所谓的异步执行其实就是使用多线程的方式实现异步调用。
    异步有什么好处呢?
    如果一个业务逻辑执行完成需要多个步骤,也就是调用多个方法去执行,
    这个时候异步执行比同步执行相应更快。不过要注意异步请求的顺序和处理结果的顺序最好一致,不然就达不到效果了。

    启用异步

    需要在应用入口类上添加:@EnableAsync

    @EnableAsync
    @SpringBootApplication
    @IntegrationComponentScan("com.ztjy")
    public class MyApplication {
        public static void main(String[] args) {
                SpringApplication.run(MyApplication.class, args);
       }
    

    定义一个线程池

    @Configuration
    public class AsyncTaskPoolConfig {
    
        @Bean(name = "taskExecutor")
        public Executor taskExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(10);
            executor.setMaxPoolSize(200);
            executor.setQueueCapacity(50);
            executor.setKeepAliveSeconds(60);
            executor.setThreadNamePrefix("taskExecutor-ws-");
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            return executor;
        }
    }
    

    编写异步请求

    在异步执行的方法上添加注解:@Async

    Component
    @Log4j2
    public class AsyncTask {
    
        //这里注入的是dubbo的服务,和异步请求没有多大关系
        @Reference(check = false)
        private AuthorFacade authorFacade;
    
          /**
         * 获取作者信息
         *
         * @param authorId 作者ID
         * @return 作者信息
         */
        @Async
        public Future<AuthorDTO> getAuthor(String authorId){
            try {
                System.out.println("执行线程的名字:"+Thread.currentThread().getName());
                return new AsyncResult<AuthorDTO>(authorFacade.getAuthor(authorId));
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
    }
    

    在service里调用异步执行的方法

    /**
         * 异步调用获取文章信息
         *
         * @param articleId 文章ID
         * @return 文章信息
         */
        @Override
        public Map getArticleDetailAsync(String articleId){
            //同步调用获取文章信息
            ArticleDTO articleDTO = articleFacade.getArticle(articleId);
            //异步调用获取作者信息
            Future<AuthorDTO> authorFuture = asyncTask.getAuthor(articleDTO.getAuthorId());
    
            Map<String,Object> map=new HashMap<>(10);
            map.put("article",articleDTO);
            try{
                map.put("author",authorFuture.get());
            }catch (Exception e){
                log.error(e.getMessage());
            }
            return map;
        }
    

    注意

    如果出现循环了依赖的问题:
    https://www.qingtingip.com/h_309979.html
    尽量不要在本类中异步调用
    尽量不要有返回值
    不能使用本类的私有方法或者非接口化加注@Async,因为代理不到失效
    异步方法不能使用static修饰
    异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类
    类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象
    如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解
    在调用Async方法的方法上标注@Transactional是管理调用方法的事务的
    在Async方法上标注@Transactional是管理异步方法的事务,事务因线程隔离

    使用过程中可能遇到循环依赖或者异步失效,事务的问题,可以参考:
    作者:锦成同学
    链接:https://juejin.im/post/5d47a80a6fb9a06ad3470f9a
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    vue 组件的封装
    原生tab选项卡
    vue 登录验证码
    input type=”file“ change事件只执行一次的问题
    Java容器解析系列(13) WeakHashMap详解
    Java容器解析系列(12) LinkedHashMap 详解
    Java容器解析系列(11) HashMap 详解
    Java泛型之自限定类型
    java Reference
    Thread类源码解析
  • 原文地址:https://www.cnblogs.com/wangsen/p/11656683.html
Copyright © 2020-2023  润新知