spring注解 @EnableAsync @Async实现异步调用(实例)

2022-06-14 11:09:11

对于一些简单的场景而言,其实spring的异步注解就非常好用.
本篇以SpringBoot项目为讲解:

一、生效步骤

1)配置@EnableAsync到启动类上

@EnableAsyncpublicclassApplicationextendsWebMvcConfigurationSupport{

2)在需要异步的方法或者某个类上配置@Async

2.1 注入到类上,该类的全部方法在其他地方调用都会是异步

@Service@AsyncpublicclassAsyncService{publicvoidasyncSleep2(){
		System.out.println("次线程2 "+ Thread.currentThread().getName());
		System.out.println("次线程2 开始异步休眠3秒");try{
			Thread.sleep(3000);}catch(InterruptedException e){
			e.printStackTrace();}
		System.out.println("次线程2 异步休眠休眠结束");}publicvoidasyncSleep1(){
		System.out.println("次线程1 "+ Thread.currentThread().getName());
		System.out.println("次线程1 开始异步休眠3秒");try{
			Thread.sleep(3000);}catch(InterruptedException e){
			e.printStackTrace();}
		System.out.println("次线程1 异步休眠休眠结束");}}

2.2 注入到方法上,当被其他调用,则会异步

@AsyncpublicvoidasyncSleep2(){
		System.out.println("次线程2 "+ Thread.currentThread().getName());
		System.out.println("次线程2 开始异步休眠3秒");try{
			Thread.sleep(3000);}catch(InterruptedException e){
			e.printStackTrace();}
		System.out.println("次线程2 异步休眠休眠结束");}

二、同类可以实现异步吗?

用this肯定是不可行的,那我本类里注入一个本Service,可以实现吗?答案也是不可以的,项目都没办法启动,错误如下:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name'async1Controller': Unsatisfied dependency expressed through field'asyncService'; nested exception is 
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name'asyncSayService1': Bean with name'asyncSayService1' has been injected into other beans[asyncSayService1] 
in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beansdo not use thefinal version of the bean. 
This is often the result of over-eager type matching- consider using'getBeanNamesForType' with the'allowEagerInit' flag turned off,for example.

三、接口和实现类,该如何配置异步注解?

有实现类继承接口的形式,可以实现异步吗?
答案也是不可行的,可自行测试。

四、demo测试

public IntegergetAsyncHello1(){
		System.out.println("getAsyncHello1-Start 主线程1:"+Thread.currentThread().getName());
		asyncService.asyncSleep1();
		System.out.println("getAsyncHello1-End");return1;}

asyncSleep1是一个异步方法,我将注解配置到了类上,就代表着我这个类里的所有方法都是需要异步实现的。

publicvoidasyncSleep1(){
		System.out.println("次线程1 "+ Thread.currentThread().getName());
		System.out.println("次线程1 开始异步休眠3秒");try{
			Thread.sleep(3000);}catch(InterruptedException e){
			e.printStackTrace();}
		System.out.println("次线程1 异步休眠休眠结束");}

如果asyncSleep1异步的话,那么如上我们应该打印出getAsyncHello1主线程的两个输出,然后再打印次线程的输出,并且我们通过输出可以看到线程名也不一样,就证明是开启了两个线程
在这里插入图片描述

简简单单的两个注解,就实现了异步操作。下篇讲述原理,从根源来了解实现。

  • 作者:咖啡不苦**
  • 原文链接:https://blog.csdn.net/huo065000/article/details/123468152
    更新时间:2022-06-14 11:09:11