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
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM