启动加上@EnableAsync ,需要执行异步方法上加入@Async。

在方法上加上@Async之后 底层使用多线程技术。

不使用异步

先关代码:

package com.yiyang.myfirstspringdemo.controller;

import com.yiyang.myfirstspringdemo.service.HelloService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController
@Slf4j
public class HelloController { @Resource
private HelloService helloService; @GetMapping("/helloAsync")
public String helloAsync() {
log.info("1");
helloService.addHello();
log.info("4");
return "hello world ==== async";
}
}
package com.yiyang.myfirstspringdemo.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import javax.annotation.Resource; /**
* @Author 刘翊扬
* @Date 2020/10/3 3:14 下午
* @Version 1.0
*/
@Service
@Slf4j
public class HelloService { public void addHello() {
log.info("2");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("3");
} }

不使用异步处理。

正常输出的顺序:1 2 3 4

2020-10-03 15:49:41,174  INFO HelloController:24 - 1
2020-10-03 15:49:41,175 INFO HelloService:22 - 2
2020-10-03 15:49:43,182 INFO HelloService:29 - 3
2020-10-03 15:49:43,182 INFO HelloController:26 - 4
2020-10-03 15:49:43,185 INFO LogAspect:51 - RESPONSE : hello world ==== async

使用异步

在addHello()方法上面加上@Async

同时,启动类上开启异步调用

package com.yiyang.myfirstspringdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync; @SpringBootApplication(scanBasePackages = {"com.yiyang.myfirstspringdemo"})
//@SpringBootApplication
@EnableAsync // 开启异步调用
public class MyFirstSpringDemoApplication { public static void main(String[] args) {
SpringApplication.run(MyFirstSpringDemoApplication.class, args);
} }

再次访问,结果是:1 4 2 3

2020-10-03 15:52:52,660  INFO HelloController:24 - 1
2020-10-03 15:52:52,666 INFO HelloController:26 - 4
2020-10-03 15:52:52,675 INFO HelloService:23 - 2
2020-10-03 15:52:52,675 INFO LogAspect:51 - RESPONSE : hello world ==== async
2020-10-03 15:52:54,681 INFO HelloService:30 - 3

注意:在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解会失效

例如:

改造HelloService

package com.yiyang.myfirstspringdemo.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; /**
* @Author 刘翊扬
* @Date 2020/10/3 3:14 下午
* @Version 1.0
*/
@Service
@Slf4j
public class HelloService { public void addHello() {
log.info("2");
sendMessage();
log.info("3");
} @Async
public void sendMessage() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("发送消息!!!!!");
}
}

访问结果是:1 2 3 4

2020-10-03 15:55:51,449  INFO HelloController:24 - 1
2020-10-03 15:55:51,585 INFO HelloService:17 - 2
2020-10-03 15:55:53,595 INFO HelloService:29 - 发送消息!!!!!
2020-10-03 15:55:53,596 INFO HelloService:19 - 3
2020-10-03 15:55:53,598 INFO HelloController:26 - 4
2020-10-03 15:55:53,599 INFO LogAspect:51 - RESPONSE : hello world ==== async

解决办法。。。。。。

讲sendMessage()方法放到别的类里面。

新建SendMessageService类

package com.yiyang.myfirstspringdemo.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; /**
* @Author 刘翊扬
* @Date 2020/10/3 3:37 下午
* @Version 1.0
*/
@Service
@Slf4j
public class SendMessageService { @Async
public void sendMessage() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("发送消息!!!!!");
log.info("5");
}
}

修改HelloService的内容

package com.yiyang.myfirstspringdemo.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import javax.annotation.Resource; /**
* @Author 刘翊扬
* @Date 2020/10/3 3:14 下午
* @Version 1.0
*/
@Service
@Slf4j
public class HelloService { @Resource
private SendMessageService sendMessage; public void addHello() {
log.info("2");
sendMessage.sendMessage();
log.info("3");
}
}

访问结果是:1 2 3 4 5

2020-10-03 16:00:30,870  INFO HelloController:24 - 1
2020-10-03 16:00:30,871 INFO HelloService:22 - 2
2020-10-03 16:00:30,875 INFO HelloService:24 - 3
2020-10-03 16:00:30,891 INFO HelloController:26 - 4
2020-10-03 16:00:30,901 INFO LogAspect:51 - RESPONSE : hello world ==== async
2020-10-03 16:00:32,889 INFO SendMessageService:23 - 发送消息!!!!!
2020-10-03 16:00:32,890 INFO SendMessageService:24 - 5

那么为什么,在同一类中一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解会失效呢????

看这个博客:https://blog.csdn.net/clementad/article/details/47339519

SpringBoot2.3中@Async实现异步的更多相关文章

  1. ASP.NET sync over async(异步中同步,什么鬼?)

    async/await 是我们在 ASP.NET 应用程序中,写异步代码最常用的两个关键字,使用它俩,我们不需要考虑太多背后的东西,比如异步的原理等等,如果你的 ASP.NET 应用程序是异步到底的, ...

  2. Spring中@Async注解实现“方法”的异步调用

    原文:http://www.cnblogs.com/zhengbin/p/6104502.html 简单介绍: Spring为任务调度与异步方法执行提供了注解支持.通过在方法上设置@Async注解,可 ...

  3. HTML5中script的async属性异步加载JS

    HTML5中script的async属性异步加载JS     HTML4.01为script标签定义了5个属性: charset 可选.指定src引入代码的字符集,大多数浏览器忽略该值.defer 可 ...

  4. spring boot中使用@Async实现异步调用任务

    本篇文章主要介绍了spring boot中使用@Async实现异步调用任务,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 什么是“异步调用”? “异步调用”对应的是“同步 ...

  5. 【转】C# Async/Await 异步编程中的最佳做法

    Async/Await 异步编程中的最佳做法 Stephen Cleary 近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支 ...

  6. 如何在项目中使用Spring异步调用注解@Async

    本文主要介绍如何使用Spring框架提供的异步调用注解@Async,异步线程池配置.异常捕获处理. 开启@Async注解支持 使用@Async注解的之前,必须在项目中启动时调用@EnableAsync ...

  7. .NET Web应用中为什么要使用async/await异步编程

    前言 什么是async/await? await和async是.NET Framework4.5框架.C#5.0语法里面出现的技术,目的是用于简化异步编程模型. async和await的关系? asy ...

  8. C#中 Thread,Task,Async/Await 异步编程

    什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调 ...

  9. C++11中async中future用法(一)

    async意味着异步执行代码,看如下示例: #include <future> #include <thread> #include <chrono> #inclu ...

随机推荐

  1. idea 执行maven打包命令时,修改war包名称

  2. 洛谷P3817 小A的糖果 贪心思想

    一直觉得洛谷的背景故事很....直接题解吧 #include <bits/stdc++.h> //万能头文件 using namespace std; int a[100002]; // ...

  3. Android开发之清除缓存功能实现方法,可以集成在自己的app中,增加一个新功能。

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 Android开发之清除缓存功能实现方法,可以集成在自己的app中,增加一个新功能. 下面是一个效果图 ...

  4. light Map

    Unity5中lightmap的坑 http://blog.csdn.net/langresser_king/article/details/48914901 Unity中光照贴图一二坑及解决办法 h ...

  5. 重要bug记录

    导唱功能:需求点分析:本地已下载歌曲播放,判断是否有音频原唱伴奏版权,无版权按钮显示“导唱”,有版权显示“播原唱”.程序实现逻辑: 1.下载歌曲时调用一个歌曲信息接口,返回歌曲的一些属性信息,其中包括 ...

  6. 干货 | 45张图庖丁解牛18种Queue,你知道几种?

    在讲<21张图讲解集合的线程不安全>那一篇,我留了一个彩蛋,就是Queue(队列)还没有讲,这次我们重点来看看Java中的Queue家族,总共涉及到18种Queue.这篇恐怕是市面上最全最 ...

  7. 给MySQL中数据表添加字段

    添加一个char字段: mysql> alter table stock add src char(20); Query OK, 3766 rows affected (0.65 sec) Re ...

  8. MySQL通过实体经纬度字段插入数据库point类型的经纬度字段

    说明:数据库:表中没有经度跟纬度字段,只有location字段(point类型) POINT(经度 纬度)实体类:只有经度 lng 字段.纬度 lat 字段 没有location字段 <!--添 ...

  9. get_started_3dsctf_2016

    题外:这道题不是很难,但是却难住了我很久.主要是在IDA中查看反编译出的伪代码时双击了一下gets()函数,结果进入gets函数内部,我当时就懵了,误以为这是一个自定义函数,但是自定义函数应该应该不能 ...

  10. My97DatePicker时间控件使用方法

    引入css及js <asp:TextBox ID="tb_startTime" runat="server" CssClass="Wdate&q ...