本文共 8364 字,大约阅读时间需要 27 分钟。
Spring Boot任务调度实践
概要
在开发Web应用时,任务调度功能是提升系统效率的重要组成部分。常见的任务类型包括异步任务、定时任务和邮件任务。本文以数据库报表为例,探讨任务调度如何优化系统设计。
异步任务
异步任务能够有效减少用户等待时间,提升用户体验。以下是异步任务的实现步骤。
1. 无返回值异步任务调用
a. Spring Boot项目创建
选择Web模块中的Web依赖,完成项目初始化。
b. 编写异步调用方法
创建业务实现类MyAsyncService,并编写模拟发送短信验证码的方法。
@Servicepublic class MyAsyncService { @Async public void sendSMS() throws Exception { System.out.println("调用短信验证码业务方法..."); Long startTime = System.currentTimeMillis(); Thread.sleep(5000); Long endTime = System.currentTimeMillis(); System.out.println("短信业务执行完成耗时:" + (endTime - startTime)); }} c. 开启基于注解的异步任务支持
在主类SpringMissionApplication中添加注解,启用异步任务支持。
@EnableAsync@SpringBootApplicationpublic class SpringMissionApplication { public static void main(String[] args) { SpringApplication.run(SpringMissionApplication.class, args); }} d. 编写控制层业务调用方法
创建控制类MyAsyncController,并实现异步方法调用。
@Controllerpublic class MyAsyncController { @Autowired private MyAsyncService myService; @GetMapping("/sendSMS") @ResponseBody public String sendSMS() throws Exception { Long startTime = System.currentTimeMillis(); myService.sendSMS(); Long endTime = System.currentTimeMillis(); System.out.println("主流程耗时: " + (endTime - startTime)); return "success"; }} e. 异步任务效果测试
访问http://localhost:8080/sendSMS,观察异步任务执行效果。
2. 有返回值异步任务调用
a. 编写异步调用方法
在MyAsyncService中添加两个有返回值的异步方法。
@Asyncpublic FutureprocessA() throws Exception { System.out.println("开始分析并统计业务A数据..."); Long startTime = System.currentTimeMillis(); Thread.sleep(4000); int count = 123456; Long endTime = System.currentTimeMillis(); System.out.println("业务A数据统计耗时:" + (endTime - startTime)); return new AsyncResult (count);}@Asyncpublic Future processB() throws Exception { System.out.println("开始分析并统计业务B数据..."); Long startTime = System.currentTimeMillis(); Thread.sleep(5000); int count = 654321; Long endTime = System.currentTimeMillis(); System.out.println("业务B数据统计耗时:" + (endTime - startTime)); return new AsyncResult (count);}
b. 编写控制层业务调用方法
在MyAsyncController中实现异步方法的调用和结果处理。
@GetMapping("/statistics")public String statistics() throws Exception { Long startTime = System.currentTimeMillis(); Future futureA = myService.processA(); Future futureB = myService.processB(); int total = futureA.get() + futureB.get(); System.out.println("异步任务数据统计汇总结果:" + total); Long endTime = System.currentTimeMillis(); System.out.println("主流程耗时: " + (endTime - startTime)); return "success";} c. 异步任务效果测试
访问http://localhost:8080/statistics,观察异步任务并行执行效果。
定时任务
1. 介绍
Spring Boot支持基于注解的定时任务配置,包括fixedRate、fixedDelay和cron属性。
2. 定时任务实现
a. 编写定时任务业务处理方法
创建定时任务服务类ScheduledTaskService,并编写定时任务方法。
@Servicepublic class ScheduledTaskService { private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private Integer count1 = 1; private Integer count2 = 1; private Integer count3 = 1; @Scheduled(fixedRate = 60000) public void scheduledTaskImmediately() { System.out.println(String.format("fixedRate第%s次执行,当前时间为:%s", count1++, dateFormat.format(new Date()))); } @Scheduled(fixedDelay = 60000) public void scheduledTaskAfterSleep() throws InterruptedException { System.out.println(String.format("fixedDelay第%s次执行,当前时间为:%s", count2++, dateFormat.format(new Date()))); Thread.sleep(10000); } @Scheduled(cron = "0 * * * * *") public void scheduledTaskCron() { System.out.println(String.format("cron第%s次执行,当前时间为:%s", count3++, dateFormat.format(new Date()))); }} b. 开启基于注解的定时任务支持
在主类中添加定时任务注解,完成配置。
@EnableScheduling@EnableAsync@SpringBootApplicationpublic class SpringMissionApplication { public static void main(String[] args) { SpringApplication.run(SpringMissionApplication.class, args); }} c. 定时任务效果测试
通过控制台观察定时任务的执行情况。
邮件任务
1. 发送纯文本邮件
a. 添加邮件服务依赖
在项目依赖中添加邮件服务依赖启动器。
org.springframework.boot spring-boot-starter-mail
b. 添加邮件服务配置
配置QQ邮箱服务器参数。
spring.mail.host=smtp.qq.comspring.mail.port=587spring.mail.username=2127269781@qq.comspring.mail.password=ijdjokspcbnzfbfaspring.mail.default-encoding=UTF-8spring.mail.properties.mail.smtp.connectiontimeout=5000spring.mail.properties.mail.smtp.timeout=3000spring.mail.properties.mail.smtp.writetimeout=5000
c. 定制邮件发送服务
创建邮件发送服务类SendEmailService,实现纯文本邮件发送。
@Servicepublic class SendEmailService { @Autowired private JavaMailSenderImpl mailSender; @Value("${spring.mail.username}") private String from; @Autowired private TemplateEngine templateEngine; public void sendSimpleEmail(String to, String subject, String text) { try { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom(from); message.setTo(to); message.setSubject(subject); message.setText(text); mailSender.send(message); System.out.println("纯文本邮件发送成功"); } catch (MailException e) { System.out.println("纯文本邮件发送失败 " + e.getMessage()); e.printStackTrace(); } }} d. 邮件发送效果测试
在测试类中实现邮件发送功能测试。
@SpringBootTestclass SpringMissionApplicationTests { @Autowired private SendEmailService sendEmailService; @Test public void sendSimpleMailTest() { String to = "2127269781@qq.com"; String subject = "【纯文本邮件】标题"; String text = "Spring Boot纯文本邮件发送内容测试....."; sendEmailService.sendSimpleEmail(to, subject, text); }} 2. 发送带附件和图片的邮件
a. 定制邮件发送服务
在SendEmailService中添加复杂邮件发送方法。
public void sendComplexEmail(String to, String subject, String text, String filePath, String rscId, String rscPath) { try { MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); helper.setText(text, true); FileSystemResource res = new FileSystemResource(new File(rscPath)); helper.addInline(rscId, res); FileSystemResource file = new FileSystemResource(new File(filePath)); String fileName = filePath.substring(filePath.lastIndexOf(File.separator())); helper.addAttachment(fileName, file); mailSender.send(message); System.out.println("复杂邮件发送成功"); } catch (MessagingException e) { System.out.println("复杂邮件发送失败 " + e.getMessage()); e.printStackTrace(); }} b. 邮件发送效果测试
在测试类中实现复杂邮件发送功能测试。
@Testpublic void sendComplexEmailTest() { String to = "2127269781@qq.com"; String subject = "【复杂邮件】标题"; String text = "祝大家元旦快乐!
"; String rscId = "img001"; String rscPath = "F:\\email\\newyear.jpg"; String filePath = "F:\\email\\元旦放假注意事项.docx"; sendEmailService.sendComplexEmail(to, subject, text.toString(), filePath, rscId, rscPath);} 3. 发送模板邮件
a. 添加Thymeleaf模板引擎依赖
在项目依赖中添加Thymeleaf模板引擎依赖启动器。
org.springframework.boot spring-boot-starter-thymeleaf
b. 定制模板邮件
创建HTML邮件模板文件emailTemplate_vercode.html。
用户验证码 XXX先生/女士,您好:您的新用户验证码为123456,请妥善保管。
c. 定制邮件发送服务
在SendEmailService中实现HTML模板邮件发送。
public void sendTemplateEmail(String to, String subject, String content) { try { MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); helper.setText(content, true); mailSender.send(message); System.out.println("模板邮件发送成功"); } catch (MessagingException e) { System.out.println("模板邮件发送失败 " + e.getMessage()); e.printStackTrace(); }} d. 模板邮件发送效果测试
在测试类中实现模板邮件发送功能测试。
@Autowiredprivate TemplateEngine templateEngine;@Testpublic void sendTemplateEmailTest() { String to = "2127269781@qq.com"; String subject = "【模板邮件】标题"; Context context = new Context(); context.setVariable("username", "石头"); context.setVariable("code", "456123"); String emailContent = templateEngine.process("emailTemplate_vercode", context); sendEmailService.sendTemplateEmail(to, subject, emailContent);} 结论
通过以上配置和实现,可以在Spring Boot项目中完成异步任务、定时任务和邮件任务的集成与调度。这些功能能够显著提升系统的性能和用户体验。
发表评论
最新留言
关于作者