对于一些简单的场景而言,其实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主线程的两个输出,然后再打印次线程的输出,并且我们通过输出可以看到线程名也不一样,就证明是开启了两个线程
简简单单的两个注解,就实现了异步操作。下篇讲述原理,从根源来了解实现。