首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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

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的本身就是在同一个类中无法调用,故此通过其实现的注解也是无法同类之内使用。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200718A06X8K00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券