SpringBoot2.3中@Async实现异步

    科技2022-07-11  107

    启动加上@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

    Processed: 0.035, SQL: 8