介紹
所謂的異步執行其實就是使用多線程的方式實現異步調用。
異步有什么好處呢?
如果一個業務邏輯執行完成需要多個步驟,也就是調用多個方法去執行,
這個時候異步執行比同步執行相應更快。不過要注意異步請求的順序和處理結果的順序最好一致,不然就達不到效果了。
啟用異步
需要在應用入口類上添加:@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
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。