0、序言
我们在正常开发中一般都是通过同步的方式进行处理的,但是有时候执行多个任务并不是都需要一起执行完才行,采取异步的方式可以有效提升一个请求响应的时间。例如我们进行用户注册,如果是通过邮箱注册一般会发送激活邮件,系统添加用户信息到数据库和发送邮件这2个任务完全可以分开来做,这样用户可以很快接受到注册成功的消息。
接下来就是 SpringBoot 异步编程具体操作。
SpringBoot 异步编程拢共分2步。
1、在SpringBoot 启动类上声明@EnableAsync
具体代码如下:
package cn.lijunkui;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication@EnableAsync //开启异步调用public class SpringbootexamplesApplication { public static void main(String[] args) { SpringApplication.run(SpringbootexamplesApplication.class, args); }}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync //开启异步调用
public class SpringbootexamplesApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootexamplesApplication.class, args);
}
}
2、在需要进行异步处理的方法上声明@Async
我们模拟一下用户注册流程代码 添加用户到数据库和邮件发送都都通过打印信息来进行展示。不再进行数据库和邮件发送配置相关操作了。
我们用户注册到数据库采用同步方式 我们发送邮件需要采取异步,所以我们需要在邮件服务发送邮件的方法上声明@Async。具体演示类代码如下:
用户类代码如下:
package cn.lijunkui.user.model;public class User { private String name; private Integer age; //省略get and set 方法.... @Override public String toString() { return "User [name=" + name + ", age=" + age + "]"; }}
public class User {
private String name;
private Integer age;
//省略get and set 方法....
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
用户Dao类:
package cn.lijunkui.user.dao;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Repository;import cn.lijunkui.user.model.User;@Repositorypublic class UserDao { Logger log = LoggerFactory.getLogger(UserDao.class); public void insert(User user) { log.info("添加用户成功 用户信息 {}",user.toString()); }}import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import cn.lijunkui.user.model.User;
@Repository
public class UserDao {
Logger log = LoggerFactory.getLogger(UserDao.class);
public void insert(User user) {
log.info("添加用户成功 用户信息 {}",user.toString());
}
}
用户服务类:
package cn.lijunkui.user.service;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import cn.lijunkui.user.dao.UserDao;import cn.lijunkui.user.model.User;@Servicepublic class UserService { Logger log = LoggerFactory.getLogger(UserService.class); @Autowired private UserDao userDao; @Autowired private MailService mailService; public long addUser(User user) throws InterruptedException{ long startTime = System.currentTimeMillis(); userDao.insert(user); mailService.send(user); long endTime = System.currentTimeMillis(); log.info("注册耗时:"+(endTime - startTime)); return (endTime - startTime); }}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.lijunkui.user.dao.UserDao;
import cn.lijunkui.user.model.User;
@Service
public class UserService {
Logger log = LoggerFactory.getLogger(UserService.class);
@Autowired
private UserDao userDao;
@Autowired
private MailService mailService;
public long addUser(User user) throws InterruptedException{
long startTime = System.currentTimeMillis();
userDao.insert(user);
mailService.send(user);
long endTime = System.currentTimeMillis();
log.info("注册耗时:"+(endTime - startTime));
return (endTime - startTime);
}
}
用户邮箱服务类:
邮箱服务类发送邮箱方法send 声明@Async 并在方法内通过 Thread.sleep(2000); 延时2秒操作。
package cn.lijunkui.user.service;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;import cn.lijunkui.user.model.User;@Servicepublic class MailService { Logger log = LoggerFactory.getLogger(MailService.class); @Async public void send(User user) throws InterruptedException { long start = System.currentTimeMillis(); Thread.sleep(2000); long end = System.currentTimeMillis(); log.info("发送激活邮箱成功!"+(end-start)+"ms"); }}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import cn.lijunkui.user.model.User;
@Service
public class MailService {
Logger log = LoggerFactory.getLogger(MailService.class);
@Async
public void send(User user) throws InterruptedException {
long start = System.currentTimeMillis();
Thread.sleep(2000);
long end = System.currentTimeMillis();
log.info("发送激活邮箱成功!"+(end-start)+"ms");
}
}
用户Controller:
package cn.lijunkui.user.controller;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import cn.lijunkui.user.model.User;import cn.lijunkui.user.service.UserService;@RestController@RequestMapping("/user")public class UserController { @Autowired private UserService userService; @GetMapping("/addUser") public String addUser(User user) throws InterruptedException { long time = userService.addUser(user); return "注册耗时:"+time; }}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.lijunkui.user.model.User;
import cn.lijunkui.user.service.UserService;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/addUser")
public String addUser(User user) throws InterruptedException {
long time = userService.addUser(user);
return "注册耗时:"+time;
}
}
进行测试:
启动我们的服务 通过游览器访问我们添加用户Controller 具体操作结果如下:
我的后台控制期打印日志内容如下: