为了提高服务的响应效率,我们需要用到方法的异步调用,之前大部分都是使用多线程来完成此类任务,其实,在spring 3.x之后,就已经内置了@Async来完美解决这个问题,本文将介绍在springboot中如何使用@Async。
1 在pom.xml文件中引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
2 写一个springboot的启动类:
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* @author mazhen
* @className AdminApplication
* @Description 启动类
* @date 2020/9/28 14:43
*/
@EnableAsync
@ComponentScan("com.mazhen")
@MapperScan(basePackages = "com.mazhen.admin.mapper")
@SpringBootApplication
public class AdminApplication {
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class,args);
}
}
注意,在这里一定要加上@EnableAsync注解开启异步调用。
3 新建一个TestController类,用来获取请求
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.mazhen.service.UserService;
@RestController
public class TestController {
@Autowired
private UserService userService;
@RequestMapping("/asyncTest")
public String asyncTest(){
System.out.println("####TestController##### 1");
userService.sendMessage();
System.out.println("####TestController##### 4");
return "success";
}
}
4 新建一个UserService类
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Async
public void sendMessage(){
System.out.println("####sendMessage#### 2");
IntStream.range(0, 5).forEach(d -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("####sendMessage#### 3");
}
}
测试
先注掉@EnableAsync和@Async两个注解,看下同步调用执行的效果。执行结果如下:
####TestController##### 1
####sendMessage#### 2
####sendMessage#### 3
####TestController##### 4
开启@EnableAsync和@Async两个注解,执行结果如下:
####TestController##### 1
####TestController##### 4
####sendMessage#### 2
####sendMessage#### 3
总结
1、使用了@Async的方法,会被当成是一个子线程,所以整个sendMessage方法,会在主线程执行完了之后执行
2、同一个类中,一个方法调用另外一个有@Async的方法,注解是不会生效的
自定义线程池:https://blog.csdn.net/weixin_34248258/article/details/88018956