学科分类
目录
Spring Boot开发

无返回值异步任务调用

在实际开发中,项目可能会向新注册用户发送短信验证码,这时,可以考虑使用异步任务调用的方式实现,一方面是因为用户对这个时效性要求没有特别高,另一方面在特定时间范围内没有收到验证码,用户可以点击再次发送验证码。下面,使用Spring Boot框架演示这种场景需求,进一步说明无返回值的异步任务调用。

(1)Spring Boot项目创建

使用Spring Initializr方式创建一个名为chapter09的Spring Boot项目,在Dependencies依赖中选择Web模块中的Web依赖。

需要说明的是,Spring框架提供了对异步任务的支持,Spring Boot框架继承了这一异步任务功能,在Spring Boot中整合异步任务时,只需在项目中引入Web模块中的Web依赖可以使用这种异步任务功能。

(2)编写异步调用方法

在chapter09项目中创建名为com.itheima.service的包,并在该包下创建一个业务实现类MyAsyncService,在该类中模拟编写用户短信验证码发送的方法,内容如文件1所示。

文件1 MyAsyncService.java

 1    import org.springframework.scheduling.annotation.Async;
 2    import org.springframework.stereotype.Service;
 3    @Service
 4    public class MyAsyncService{
 5        @Async
 6        public void sendSMS() throws Exception {
 7            System.out.println("调用短信验证码业务方法...");
 8            Long startTime = System.currentTimeMillis();
 9            Thread.sleep(5000);
 10            Long endTime = System.currentTimeMillis();
 11            System.out.println("短信业务执行完成耗时:" + (endTime - startTime));
 12        }
 13    }

文件1中,sendSMS()方法模拟实现用户短信验证码发送功能,在方法上方使用Spring框架提供的@Async注解,表明该方法是一个异步方法。在sendSMS()方法中,使用了Thread.sleep(5000)方法模拟业务调用耗时,并打印了业务耗时统计。

(3)开启基于注解的异步任务支持

上一步编写的用户短验证码发送业务方法中,使用@Async注解标记了异步方法,如果在Spring Boot中希望异步方法生效,还需要使用@EnableAsync注解开启基于注解的异步任务支持。@EnableAsync注解通常会添加在项目启动类上,内容如文件2所示。

文件2 Chapter09Application.java

 1    import org.springframework.boot.SpringApplication;
 2    import org.springframework.boot.autoconfigure.SpringBootApplication;
 3    import org.springframework.scheduling.annotation.EnableAsync;
 4    @EnableAsync        // 开启基于注解的异步任务支持
 5    @SpringBootApplication
 6    public class Chapter09Application {
 7        public static void main(String[] args) {
 8            SpringApplication.run(Chapter09Application.class, args);
 9        }
 10    }

(4)编写控制层业务调用方法

在chapter09项目中创建名为com.itheima.controller的包,并在该包下创建一个异步方法调用的实现类MyAsyncController,在该类中模拟编写用户短信验证码发送的处理方法,内容如文件3所示。

文件3 MyAsyncController.java

 1    import com.itheima.service.MyAsyncService;
 2    import org.springframework.beans.factory.annotation.Autowired;
 3    import org.springframework.web.bind.annotation.GetMapping;
 4    import org.springframework.web.bind.annotation.RestController;
 5    @RestController
 6    public class MyAsyncController {
 7        @Autowired
 8        private MyAsyncService myService;
 9        @GetMapping("/sendSMS")
 10        public String sendSMS() throws Exception {
 11            Long startTime = System.currentTimeMillis();
 12            myService.sendSMS();
 13            Long endTime = System.currentTimeMillis();
 14            System.out.println("主流程耗时: "+(endTime-startTime));
 15            return "success";
 16        }
 17    }

文件3中,在处理类MyAsyncController中编写了一个处理映射路径为“/sendSMS”的用户短信发送处理方法,打印了主流程耗时统计。

(5)异步任务效果测试

启动chapter09项目,项目启动成功后,在浏览器上访问“http://localhost:8080/sendSMS”测试异步任务请求,此时会发现浏览器上会快速响应“success”信息,没有出现阻塞情况,同时立即查看控制台输出效果,结果如图9-1所示。

图1 异步任务调用效果

从演示结果可以看出,执行sendSMS()方法并调用异步方法处理短信业务时,在很短的时间内(2毫秒)完成了主流程的执行,并向页面响应主流程结果,而在主流程打印输出方法之前调用的异步方法经过一段时间后才执行完毕。因此,从执行结果可以发现,案例中无返回值的异步任务调用成功。

需要说明的是,上述案例中的异步方法是没有返回值的,这样主流程在执行异步方法时不会阻塞,而是继续向下执行主流程程序,直接向页面响应结果,而调用的异步方法会作为一个子线程单独执行,直到异步方法执行完成。

点击此处
隐藏目录