天天看点

SpringBoot 异步、定时任务和邮件发送

任务

异步任务

定时任务

邮件发送

SpringBoot 异步任务

我们有这样一个情况:

// API 代码
@RequestMapping("/hello")
public String sayHello() {
    myService.printHello();
    return "OK";
}

// 业务代码
public void printHello() {
    try {
        Thread.sleep(3 * 1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("处理完成");
}
           

正常执行的话浏览器必须要在业务代码处理完之后才能加载到OK,非常不合理!

当然,我们可以使用多线程来解决这个问题——让业务代码起新的线程运行,不过这样原生的方法似乎有些麻烦,Spring 早就为我们准备好了异步任务的实现,只需要在方法上使用

@Async

注解并且在启动类上启用 Async 就可以将方法设置成异步执行:

@EnableAsync
@SpringBootApplication
public class MissionApplication {

	public static void main(String[] args) {
		SpringApplication.run(MissionApplication.class, args);
	}

}

@Async
public void printHello() {
    try {
        Thread.sleep(3 * 1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("处理完成");
}
           

这样一来浏览器就不需要等到服务器端业务代码执行完毕才能收到结果。

SpringBoot 邮件任务

在 Spring 中使用邮件简直不要太简单。首先导入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
           

进行一些简单的配置,注意这里的 password 是使用 SMTP/POP3 的密码,不是邮箱密码:

spring:
  mail:
    username: [email protected]
    password: xxxxx
    host: smtp.qq.com
    # 开启加密验证,qq 邮箱需要
    properties:
      mail:
        smtp:
          ssl:
            enable: true
           

然后在需要发送邮件的地方注入

JavaMailSenderImpl

类,使用方法如下:

void contextLoads1() {
    // 一个简单的邮件
    SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
    simpleMailMessage.setSubject("通知");
    simpleMailMessage.setText("你好世界");
    simpleMailMessage.setTo();
    simpleMailMessage.setFrom("[email protected]");
    simpleMailMessage.setTo("[email protected]");
    mailSender.send(simpleMailMessage);
}

void contextLoads2() {
		// MIME 邮件
		try {
			MimeMessage mimeMessage = mailSender.createMimeMessage();
			MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
			mimeMessageHelper.setSubject("退学通知");
			mimeMessageHelper.setText("<h1>通知</h1><p style='color:red'>xxx:\n\txxx,xxx,xxx!</p><img src='xxx'>", true);
			mimeMessageHelper.addAttachment("icon", new File("xxxx"));
			mimeMessageHelper.setFrom("[email protected]");
			mimeMessageHelper.setTo("[email protected]");
			mailSender.send(mimeMessage);
		} catch (MessagingException e) {
			e.printStackTrace();
		}
	}
           

SpringBoot 定时任务

第一步先在主启动类上开启定时:

@EnableScheduling
           

然后在要被定时执行的方法上启用定时注解并且制定 cron 表达式:

@Scheduled(cron = "3/10 * * * * ?")
           

有关 cron 表达式的内容不做赘述,网上资料、转换器成堆,在这里列一些常用的:

(1)0 0 2 1 * ? 表示在每月的1日的凌晨2点调整任务

(2)0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业

(3)0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作

(4)0 0 10,14,16 * * ? 每天上午10点,下午2点,4点

(5)0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时

(6)0 0 12 ? * WED 表示每个星期三中午12点

(7)0 0 12 * * ? 每天中午12点触发

(8)0 15 10 ? * * 每天上午10:15触发

(9)0 15 10 * * ? 每天上午10:15触发

(10)0 15 10 * * ? 每天上午10:15触发

(11)0 15 10 * * ? 2005 2005年的每天上午10:15触发

(12)0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发

(13)0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发

(14)0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发

(15)0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发

(16)0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发

(17)0 15 10 ? * MON-FRI 周一至周五的上午10:15触发

(18)0 15 10 15 * ? 每月15日上午10:15触发

(19)0 15 10 L * ? 每月最后一日的上午10:15触发

(20)0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发

(21)0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发

(22)0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发