SpringBoot2.3中@Async实现异步
启动加上@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