Spring boot如何实现异步调用

简介: Spring boot如何实现异步调用

Spring boot如何实现异步调用

异步调用:一个可以无需 等待被调用函数的返回值就让操作继续进行的方法

举个例子

异步调用就是你 喊 你朋友吃饭 ,你朋友说知道了 ,待会忙完去找你 ,你就去做别的了。
同步调用就是你 喊 你朋友吃饭 ,你朋友在忙 ,你就一直在那等,等你朋友忙完了 ,你们一起去。

我想大家都了解了,但是怎么在代码中实现,我们以往的代码都是一步步执行下去的,现在我们要求某个耗时方法,让他单独执行不考虑结果。

题目

@SpringBootTest
class GzhApplicationTests {

    @Autowired
    private AsyncTest asyncTest;

    @Test
    void contextLoads() throws Exception {
        System.out.println("---执行主线---");
        asyncTest.test1();
        System.out.println("---主线结束---");
    }
}
@Component
public class AsyncTest {

    public void test1() {
        System.out.println("---执行副本---");
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("---副本ing---");
        }
        System.out.println("---副本结束---");
    }
}

运行结果

---执行主线---
---执行副本---
---副本ing---
---副本ing---
---副本ing---
---副本ing---
---副本ing---
---副本结束---
---主线结束---

这边的结果看到了,他是先执行完副本,然后主线才结束,我们想要的是不管副本如何我们都要继续往下走,专业术语异步执行

有同学说简单,new Thread(),把副本放进去就可以了。

@Test
void contextLoads() throws Exception {
    System.out.println("---执行主线---");
    new Thread(()-> asyncTest.test1()).start();
    System.out.println("---主线结束---");
}
//---执行主线---
//---主线结束---
//---执行副本---

有人会问副本为什么没有执行完,你用的是单元测试,主程序跑完就项目就停止了,你要是不用单元测试的话,他会执行完。

当然用new Thread()可以解决,但是今天要用注解方式解决。@Async这个注解就可以解决。

@EnableAsync
@SpringBootApplication
public class GzhApplication {

    public static void main(String[] args) {
        SpringApplication.run(GzhApplication.class, args);
    }

}
@Component
public class AsyncTest {

    @Async
    public void test1() {
        System.out.println("---执行副本---");
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("---副本ing---");
        }
        System.out.println("---副本结束---");
    }
}
@SpringBootTest
class GzhApplicationTests {

    @Autowired
    private AsyncTest asyncTest;

    @Test
    void contextLoads() throws Exception {
        System.out.println("---执行主线---");
        asyncTest.test1();
        System.out.println("---主线结束---");
    }
}
---执行主线---
---主线结束---
---执行副本---

但是有同学会说不我添加了注解不行啊。这地方我们就要去来说说要注意的事项。

失效原因

  • 1.没有在@SpringBootApplication启动类当中添加注解@EnableAsync注解。
  • 2.异步方法使用注解@Async的返回值只能为void或者Future。
  • 3.没有走Spring的代理类。因为@Transactional和@Async注解的实现都是基于Spring的AOP,而AOP的实现是基于动态代理模式实现的。那么注解失效的原因就很明显了,有可能因为调用方法的是对象本身而不是代理对象,因为没有经过Spring容器。

第一个和第二个的意思很清楚,第三个的意思就是类的内部调用是无效的。方法一定要从另一个类中调用,也就是从类的外部调用。如果你想内部调用就获取其代理对象。

相关文章
|
1月前
|
并行计算 Java 数据处理
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
152 0
|
6月前
|
Java 测试技术 Spring
Spring Boot使用@Async实现异步调用
Spring Boot使用@Async实现异步调用
53 0
|
前端开发 Java 关系型数据库
【SpringBoot】微服务学习笔记七:微服务中异步调用数据提交数据库的问题
【SpringBoot】微服务学习笔记七:微服务中异步调用数据提交数据库的问题
623 0
【SpringBoot】微服务学习笔记七:微服务中异步调用数据提交数据库的问题
|
6月前
|
Java Spring
SpringBoot+async异步调用接口以及几个任务同时完成和异步接口实现和调用
SpringBoot+async异步调用接口以及几个任务同时完成和异步接口实现和调用
136 0
|
6月前
|
监控 Java
【十一】springboot整合异步调用并获取返回值
【十一】springboot整合异步调用并获取返回值
147 0
|
6月前
|
Java Spring
使用spring boot的@Async实现异步调用和线程池复用
使用spring boot的@Async实现异步调用和线程池复用
|
Java Spring
使用spring boot的@Async实现异步调用和线程池复用
使用spring boot的@Async实现异步调用和线程池复用
870 0
使用spring boot的@Async实现异步调用和线程池复用
|
前端开发 Java 测试技术
SpringBoot-27- @Async实现异步调用 什么是异步调用
异步调用是相对于同步调用的,同步调用是按照顺序进行执行任务,只有上一个任务执行完成下一个任务才能执行,异步调用是指在按照顺序执行任务的过程中不需要等待任务结果的出现,就可以顺序执行下一个任务。
93 0
|
监控 Java 调度
基于 Spring 事务的可靠异步调用实践
pringTxAsync 组件是仓储平台组(WMS6)自主研发的一个专门用于解决可靠异步调用问题的组件。 通过使用 SpringTxAsync 组件,我们成功地解决了在仓储平台(WMS6)中的异步调用需求。经过近二年多的实践并经历了两次 618 活动以及两次双 11 活动,该组件已经在我们的所有应用中稳定运行并成功应用于各种业务场景。 该组件的主要功能是实现可靠的异步调用。在异步任务的执行过程中,我们能
182 0
|
Java BI Spring
Srping注解之@Async:SpringBoot 实现异步调用
Srping注解之@Async:SpringBoot 实现异步调用
108 0