大家好,欢迎来到IT知识分享网。
Hello,大胸弟们,我们又又又见面了,今天攀哥继续为大家分享一下SpringBoot的教程,没点关注的宝宝,点一下关注。
🌲 定时任务简介
🌿 定时任务使用场景
我们在编写SpringBoot应⽤中经常会遇到这样的场景,⽐如:我需要定时地发送⼀些短信、邮件之类 的操作,也可能会定时地检查和监控⼀些标志、参数等。
比如需要在每天凌晨的时候,分析一次前一天的日志信息,Spring为我们提供了异步执行任务调度的方式。
定时任务在实际项目开发中很常见,并且定时任务可以在各种场景中应用,通过自动化操作和任务的规模化管理,提高效率、可靠性和工作质量。可以减少手动操作,避免疏忽和错误,并节省时间和人力资源的投入 。
🌿 定时任务的优点
- 简单易用:使用注解驱动的方式,简化了定时任务的配置和管理。通过添加@Scheduled注解,可以将普通的方法标记为定时任务,而不需要手动编写定时任务调度的代码。
- 内置任务调度器:Spring Boot内置了一个轻量级的任务调度器,可以方便地执行定时任务。它提供了线程池、任务管理和并发处理等功能,可以高效地管理和执行任务。
- 灵活的配置选项:@Scheduled注解支持各种配置选项,例如cron表达式、fixedRate、fixedDelay等,可以非常灵活地定义任务的触发时间和频率。这使得开发人员能够根据具体需求精确控制定时任务的执行方式
🌲 定时任务的使用
🌿 简单案例
SpringBoot为我们提供了@EnableScheduling 和 @Scheduled两个注解来实现定时任务,用法比较简单:
- 在启动器上添加注解@EnableScheduling开启定时任务
package com.moxuan.boot_03_async; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableAsync @EnableScheduling public class Boot03AsyncApplication { public static void main(String[] args) { SpringApplication.run(Boot03AsyncApplication.class, args); } }
- 创建一个java类作为定时任务的类,然后再在类中写上任务方法,在方法上加上注解@Scheduled
@Scheduled注解中的属性值:
- fixedRate: 固定频率执行,单位毫秒
- fixedDelay: 延迟执行,单位毫秒
- cron: cron表达式,指定表达式所表示的时间执行
package com.moxuan.boot_03_async.jobs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; / * 定时任务 * * 第一位,表示秒,取值0-59 * 第二位,表示分,取值0-59 * 第三位,表示小时,取值0-23 * 第四位,日期天/日,取值1-31 * 第五位,日期月份,取值1-12 * 第六位,星期,取值1-7,1表示星期天,2表示星期一 * 第七位,年份,可以留空,取值1970-2099 * */ @Component public class HeartbeatJob { private static final Logger logger = LoggerFactory.getLogger(HeartbeatJob.class); / * 检查状态1 */ @Scheduled(cron = "0 35 14 * * ?") public void checkState1() { logger.info(">>>>> cron中午14:35上传检查开始...."); logger.info(">>>>> cron中午14:35上传检查完成...."); } int count =0; / * 检查状态2 */ // @Scheduled(fixedRate = 3000) public void checkState2() { count += 1; logger.info(">>>>> fixedRate 每隔3秒检查....当前检查第"+count+"次"); } // @Scheduled(fixedDelay = 5000) public void checkStat3(){ logger.info(">>>>> fixedDelay 这是一个5秒后执行的...."); } }
🌿 cron 表达式
Cron 表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron 有如下两种语法格式:
- 秒 分 小时 日期 月份 星期 年
- 秒 分 小时 日期 月份 星期
👇 各字段的含义:
|
字段 |
允许值 |
允许的特殊字符 |
|
秒(Seconds) |
0~59的整数 |
, – * / 四个字符 |
|
分(Minutes) |
0~59的整数 |
, – * / 四个字符 |
|
小时(Hours) |
0~23的整数 |
, – * / 四个字符 |
|
日期(DayofMonth) |
1~31的整数(但是你需要考虑你月的天数) |
,- * ? / L W C 八个字符 |
|
月份(Month) |
1~12的整数或者 JAN-DEC |
, – * / 四个字符 |
|
星期(DayofWeek) |
1~7的整数或者 SUN-SAT (1=SUN) |
, – * ? / L C # 八个字符 |
|
年(可选,留空)(Year) |
1970~2099 |
, – * / 四个字符 |
每一个域都可以使用数字,也还可以出现如下特殊字符,它们的含义分别是:
- * :表示匹配该域的任意值,假如在Minutes域使用 *, 即表示每分钟都会触发事件。
- ?:只能用在 DayofMonth 和 DayofWeek 两个域。它也匹配域的任意值,但实际不会。因为 DayofMonth 和 DayofWeek 会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用 ?,而不能使用 *,如果使用 * 表示不管星期几都会触发,实际上并不是这样。
- -:表示范围,例如在 Minutes 域使用 5-20,表示从5分到20分钟每分钟触发一次
- /:表示起始时间开始触发,然后每隔固定时间触发一次,例如在Minutes域使用 5/20, 则意味着从第 5 分钟触发一次,然后每隔 20 分钟触发一次
- ,:表示列出枚举值值。例如:在 Minutes 域使用 5,20,则意味着在5和20分每分钟触发一次。
- L:表示最后,只能出现在 DayofWeek 和 DayofMonth 域,如果在 DayofWeek 域使用 5L,意味着在最后的一个星期四触发。
- W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用 5W,如果 5 日是星期六,则将在最近的工作日:星期五,即 4 日触发。如果 5 日是星期天,则在6日(周一)触发;如果 5 日在星期一 到星期五中的一天,则就在 5 日触发。另外一点,W 的最近寻找不会跨过月份。
- LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。
- #:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如 4#2 ,表示某月的第二个星期三。
✍ 举几个例子:
- 每隔5秒执行一次:*/5 * * * * ?
- 每隔1分钟执行一次:0 */1 * * * ?
- 每天23点执行一次:0 0 23 * * ?
- 每天凌晨1点执行一次:0 0 1 * * ?
- 每月1号凌晨1点执行一次:0 0 1 1 * ?
- 每月最后一天23点执行一次:0 0 23 L * ?
- 每周星期天凌晨1点实行一次:0 0 1 ? * L
- 在26分、29分、33分执行一次:0 26,29,33 * * * ?
- 每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?
- 表示在每月的1日的凌晨2点调度任务:0 0 2 1 * ? *
- 表示周一到周五每天上午10:15执行作业:0 15 10 ? * MON-FRI
- 表示2002-2006年的每个月的最后一个星期五上午10:15执行:0 15 10 ? 6L 2002-2006
🌲 定时邮件发送
🌿 发送邮件的步骤
邮件发送,在我们的日常开发中,也非常的多,Springboot 帮我们做了支持:
- 邮件发送需要引入 spring-boot-start-mail
- SpringBoot 自动配置 MailSenderAutoConfiguration
- 定义 MailProperties 内容,配置在 application.yml 中
- 自动装配 JavaMailSender
- 测试邮件发送
首先引入 pom 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
然后需要我们在全局配置文件中配置 spring.mail:
# 你的邮箱地址 spring.mail.username= # 你的授权码 spring.mail.password=XXXXXX # 邮箱服务器 spring.mail.host=smtp..com # 需要配置ssl spring.mail.properties.mail.smtp.ssl.enable=true
获取授权码:在邮箱中的 设置 -> 账户 -> 开启 pop3 和 smtp 服务
发送简单的文本邮件,在util包下新建一个EmailUtil类,专用来发送邮件(注意在EmailUtil类上添加@Component注解 ):
@Autowired private JavaMailSender javaMailSender; / * 向用户邮箱发送短信 * * @param email 收件人邮箱 */ public void sendEmailMessage(String email) { MimeMessage message = javaMailSender.createMimeMessage(); try { //获取验证码 存入redis //邮箱发送内容组成 MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setSubject("【墨轩学习网】愿世间美好与您紧紧相拥"); helper.setText("早上好!我喜欢你很久了", true); helper.setTo(email); helper.setFrom("墨轩学习网" + '<' + "@.com" + '>'); javaMailSender.send(message); logger.info("邮件发送成功!!"); } catch (MessagingException e) { logger.error("邮件发送失败!!"); } }
在定时任务中发送邮件
@Autowired EmailUtil emailUtil; @Scheduled(cron = "0 47 22 * * ?") public void sendEmail(){ emailUtil.sendEmailMessage("@.com"); }
上面的案例中虽然可以发送邮件,但是发送的简单的文本,在实际开发中往往需要按照某种格式的邮件方式去发送,比如以html的方式发送给客户,接下来我们看看如何按照html模板发送邮件:
在项目中新建ftl目录,在其中新建邮件模板:mail.ftl
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="email code">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<!--邮箱验证码模板-->
<body>
<div style="background-color:#ECECEC; padding: 35px;">
<table cellpadding="0" align="center"
style="width: 800px;height: 100%; margin: 0px auto; text-align: left; position: relative; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; font-size: 14px; font-family:微软雅黑, 黑体; line-height: 1.5; box-shadow: rgb(153, 153, 153) 0px 0px 5px; border-collapse: collapse; background-position: initial initial; background-repeat: initial initial;background:#fff;">
<tbody>
<tr>
<th valign="middle"
style="height: 25px; line-height: 25px; padding: 15px 35px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: RGB(148,0,211); background-color: RGB(148,0,211); border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px;">
<font face="微软雅黑" size="5" style="color: rgb(255, 255, 255); ">【墨轩学习网】愿世间再无难学的技术</font>
</th>
</tr>
<tr>
<td style="word-break:break-all">
<div style="padding:25px 35px 40px; background-color:#fff;opacity:0.8;">
<h2 style="margin: 5px 0px; ">
<font color="#333333" style="line-height: 20px; ">
<font style="line-height: 22px; " size="4">
尊敬的用户:</font>{0}
</font>
</h2>
<!-- 中文 -->
<p>您好!感谢您使用墨轩学习网,{1}</p><br>
<div style="width:100%;margin:0 auto;">
<div style="padding:10px 10px 0;border-top:1px solid #ccc;color:#747474;margin-bottom:20px;line-height:1.3em;font-size:12px;">
<p>墨轩学习网研发团队</p>
<p>联系我们:1032974410@.com</p>
<br>
<p>此为系统邮件,请勿回复<br>
</p>
<!--<p>©*</p>-->
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
编写邮箱工具类:
package com.moxuan.boot_03_async.util;
import com.moxuan.boot_03_async.jobs.HeartbeatJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.MessageFormat;
@Component
public class EmailUtil {
// 日志记录员
private static final Logger logger = LoggerFactory.getLogger(EmailUtil.class);
/
* 读取邮件模板
* 替换模板中的信息
*
* @param ftl 需要发送的模板
* @return
*/
public String buildContent(String ftl,Object ... objects) {
//加载邮件html模板
Resource resource = new ClassPathResource(ftl);
InputStream inputStream = null;
BufferedReader fileReader = null;
StringBuffer buffer = new StringBuffer();
String line = "";
try {
inputStream = resource.getInputStream();
fileReader = new BufferedReader(new InputStreamReader(inputStream));
while ((line = fileReader.readLine()) != null) {
buffer.append(line);
}
} catch (Exception e) {
logger.info("发送邮件读取模板失败{}", e);
} finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//替换html模板中的参数
return MessageFormat.format(buffer.toString(), objects);
}
@Autowired
private JavaMailSender javaMailSender;
/
* 向用户邮箱发送短信
*
* @param email 收件人邮箱
*/
public void sendEmailMessage(String email,String ftl,Object ... obj) {
MimeMessage message = javaMailSender.createMimeMessage();
try {
//获取验证码 存入redis
//邮箱发送内容组成
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setSubject("【墨轩学习网】愿世间美好与您紧紧相拥");
helper.setText(buildContent(ftl,obj), true);
helper.setTo(email);
helper.setFrom("墨轩学习网" + '<' + "1032974410@.com" + '>');
javaMailSender.send(message);
logger.info("邮件发送成功!!");
} catch (MessagingException e) {
logger.error("邮件发送失败!!");
}
}
}
在定时任务中发送邮件
@Autowired EmailUtil emailUtil; @Scheduled(cron = "0 34 22 * * ?") public void sendEmail(){ emailUtil.sendEmailMessage("@.com","ftl/mail.ftl","默默","早上好,今天又是元气满满的一天"); }
效果如下:
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/110083.html

