首頁/ 家居/ 正文

Spring Boot 2 非同步@Async 註解沒生效?

簡述

非同步呼叫 對應的是 同步呼叫,同步呼叫 指程式按照 定義順序 依次執行,每一行程式都必須等待上一行程式執行完成之後才能執行;非同步呼叫 指程式在順序執行時,不等待 非同步呼叫的語句 返回結果 就執行後面的程式。

Spring Boot 2 非同步@Async 註解沒生效?

在平常的開發中,為了使用非同步程式設計,開發者一般都是透過手動多執行緒實現。但Spring Boot 為了簡化開發流程,提供了非同步程式設計註解@Async。只要是在對應的方法上加入註解就可以實現非同步呼叫。

@Async使用

在啟動的Application中加入@EnableAsync

@EnableAsync

@SpringBootApplication

public class CrmToolApplication {

public static void main(String[] args) {

SpringApplication。run(CrmToolApplication。class, args);

}

}

在需要非同步呼叫的方法上加入@Async

@Service

@Slf4j

public class TestService {

@Async

public void asyncMethodWithNoReturnType() {

try {

Thread。sleep(3000);

} catch (InterruptedException e) {

e。printStackTrace();

}

log。info(“Async。。。{}”, this。getClass()。getSimpleName());

}

}

@Async註解原理分析

看下@EnableAsync註解的原始碼

@Target({ElementType。TYPE})

@Retention(RetentionPolicy。RUNTIME)

@Documented

@Import({AsyncConfigurationSelector。class})

public @interface EnableAsync {

Class annotation() default Annotation。class;

boolean proxyTargetClass() default false;

AdviceMode mode() default AdviceMode。PROXY;

int order() default 2147483647;

}

mode預設值AdviceMode。PROXY,此值含義是使用AOP實現。AOP的本質就是動態代理,動態代理的侷限在同一個類中是無法實現呼叫。

例項

@Component

@Order(1)

@Slf4j

public class StartRunner1 implements ApplicationRunner {

private final TestService testService;

public StartRunner1(TestService testService) {

this。testService = testService;

}

@Override

public void run(ApplicationArguments args) throws Exception {

log。info(“run —— {}”, this。getClass()。getSimpleName());

Thread。sleep(1000);

// testService。asyncMethodWithNoReturnType();

asyncMethodWithNoReturnType();

}

@Async

public void asyncMethodWithNoReturnType() {

try {

Thread。sleep(3000);

} catch (InterruptedException e) {

e。printStackTrace();

}

log。info(“Async。。。{}”, this。getClass()。getSimpleName());

}

}

預設情況下上面的@Async無法生效。

2020-07-18 09:09:17。269 [restartedMain] INFO c。c。t。s。StartRunner1 | 31 | - run —— StartRunner1

2020-07-18 09:09:21。290 [restartedMain] INFO c。c。t。s。StartRunner1 | 46 | - Async。。。StartRunner1

切換至呼叫TestService中的非同步方法

2020-07-18 09:10:17。464 [restartedMain] INFO c。c。t。s。StartRunner1 | 31 | - run —— StartRunner1

2020-07-18 09:10:18。472 [restartedMain] INFO c。c。t。s。StartRunner2 | 24 | - run —— StartRunner2

2020-07-18 09:10:21。492 [task-1] INFO c。c。t。s。TestService | 38 | - Async。。。TestService

可以看出執行的 執行緒發生了變化。(restartedMain,task-1)

總結

@Async 註解沒生效一般問題的就是在同一類內呼叫,Spring 的很多註解預設都是使用AOP實現,而AOP的本身就是在同一個類中無法呼叫,故此透過其實現的註解也是無法同類之內使用。

相關文章

頂部