这一节将在上一节的基础上,深入学习Spring Boot相关知识,其中主要包括@Async异步调用,自定义参数、Mybatis等。
一、使用@Async实现异步调用
要在springboot中使用异步调用方法,只要在被调用的方法上面加上@Async
就可以了;
1.准备工作
准备一个Spring Boot项目,在App类上加上@EnableAsync
注解开启异步:
package com.goldwind; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; /** * @Author: zy * @Description: 启动代码 * @Date: 2020-2-2 */ @SpringBootApplication @EnableAsync public class App { public static void main(String[] args){ //整个程序入口 启动Spring Boot项目 SpringApplication.run(App.class,args); } }
这个注解如果不加,@Async注解失效。
2、controller
在包com.goldwind.controller下,创建文件HelloController.java:
package com.goldwind.controller; import com.goldwind.service.HelloService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.time.Instant; /** * @Author: zy * @Description: 用于演示@Async异步调用 * @Date: 2020-2-4$ */ @RestController @RequestMapping("/hello") public class HelloController { @Autowired private HelloService helloService; /** * 同步方法 * @return */ @RequestMapping("/sync") public String getSyncHello(){ long n = Instant.now().toEpochMilli(); //异步 String s = helloService.syncSayHello(); long f = Instant.now().toEpochMilli(); return s + " 时间: " + (f-n); } /** * 异步方法 * @return */ @RequestMapping("/async") public String getAsyncHello(){ long n = Instant.now().toEpochMilli(); //异步 String s = helloService.asyncSayHello(); long f = Instant.now().toEpochMilli(); return s + "时间:" + (f-n); } }
3、Service
新建包com.goldwind.service,并在包下创建HelloService.java文件:
package com.goldwind.service; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @Author: zy * @Description: 用于演示@Async异步调用 * @Date: 2020-2-4$ */ @Service @Slf4j public class HelloService { @Autowired private SleepService sleepService; /** * 同步方法 * @return */ public String syncSayHello() { try { sleepService.syncSleep(); return "hello world,这是同步方法"; } catch (InterruptedException e) { log.error(e.getMessage(),e); return "error"; } } /** * 异步方法 * @return */ public String asyncSayHello() { try { log.info("主线程 " + Thread.currentThread().getName()); sleepService.asyncSleep(); return "hello world,这是异步方法"; } catch (InterruptedException e) { log.error(e.getMessage(),e); return "error"; } } }
这里为了模拟应用场景,将耗时的方法放在另一个service里面,就叫SleepService,两个方法都是休眠3秒,aysncSleep方法上面有一个@Async
注解。
package com.goldwind.service; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; /** * @Author: zy * @Description: 用于演示@Async异步调用 * @Date: 2020-2-4$ */ @Service @Slf4j public class SleepService { /** * 同步方法 * @throws InterruptedException */ public void syncSleep() throws InterruptedException { log.info("线程名: " +Thread.currentThread().getName()); log.info("开始同步休眠3秒"); Thread.sleep(3000); log.info("同步休眠结束"); } /** * 异步方法 * @throws InterruptedException */ @Async public void asyncSleep() throws InterruptedException { log.info("次线程 "+Thread.currentThread().getName()); log.info("开始异步休眠3秒"); Thread.sleep(3000); log.info("异步休眠休眠结束"); } }
4、测试
同步:访问 http://localhost:8080/hello/sync,需要3秒的时间才能收到响应;
异步:访问 http://localhost:8080/hello/asyn,可见主线程和次线程打印出来的线程名不一样,也就是Spring Boot帮我们开启了一个线程去处理。
注意事项
- 必须要加@EnableAsync注解;
- 不能在同一类下调用@Async注解的方法,比如A类下有a和b方法,b方法有@Async注解,不能直接这样a调用b,要把b放到其他类中;
- @Async也可以打在类上,这样类下面的所有方法都是异步的(被其他类调用的时候);
参考文章:
[1] 使用SpringBoot的@Async实现异步调用方法,以及自己开启新线程异步调用
原文地址:https://www.cnblogs.com/zyly/p/12258669.html
时间: 2024-10-08 09:26:03