1. 程式人生 > >@Async異步註解與SpringBoot結合使用

@Async異步註解與SpringBoot結合使用

文件中 ren param cal async onf max inf eat

當你在service層需要啟動異步線程去執行某些分支任務,又不希望顯式使用Thread等線程相關類,只想專註於實現業務邏輯代碼開發,可以使用@Async異步註解。

1、 使用@Async 異步註解

Controller層方法:

//批量插入用戶
    @RequestMapping("/user/addSystemUser")
    public void batchAddUser(@RequestParam(value = "usernameList[]",required=false) List usernameList){
        for (int i = 0; i < usernameList.size(); i++) {
            
//使用異步線程執行每一個用戶新增 userService.addUser(usernameList.get(i)); } }

Service層方法,是真正使用@Async異步註解的:

    @Transactional(propagation = Propagation.NESTED)   //如果當前事務存在,則在嵌套事務中執行。如果沒有,就新建一個事務;
    @Async
    public void addUser(SystemUser sessionUser, List<Container> containerList, Timestamp createTime){
        
// do save one User }

2、@Async異步註解使用註意點

a)該註解可使用在類、接口(包括註釋類型)或枚舉聲明

b)當被標註在方法級別時,該方法返回值要麽是void,或java.util.concurrent.Future接口實現類

3、自定義異步註解真正的執行線程類(可選)

如果懶得自己寫一個線程執行類的話,我猜SpringBoot會默認設置一些org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor類的配置。
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.lang.reflect.Method; import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; /** * 創建自定義配置的線程池 */ @Configuration @EnableAsync public class MyTaskExecutePool implements AsyncConfigurer { private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(ASyncTask.class); @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //核心線程池大小 executor.setCorePoolSize(20); //最大線程數 executor.setMaxPoolSize(40); //隊列容量 executor.setQueueCapacity(50); //活躍時間 executor.setKeepAliveSeconds(30); //線程名字前綴 executor.setThreadNamePrefix("MyTaskExecutePool-"); // setRejectedExecutionHandler:當pool已經達到max size的時候,如何處理新任務 // CallerRunsPolicy:不在新線程中執行任務,而是由調用者所在的線程來執行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } /** * 異步任務中異常處理 * @return */ @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new AsyncUncaughtExceptionHandler() { @Override public void handleUncaughtException(Throwable arg0, Method arg1, Object... arg2) { //紀錄log錯誤日誌 LOG.error("exception method:"+arg1.getName()+";"+arg0.getMessage(), arg0); } }; } }

4、日誌監控異步線程活動(可選)

logback.xml配置文件中設置 %thread 紀錄線程執行名

<!--輸出到控制臺-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 級別過濾器。如果日誌級別低於WARN,將被過濾掉。 ALL TRACE DEBUG INFO WARN ERROR-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %msg - %file:%line%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

 

@Async異步註解與SpringBoot結合使用