10.任务
10.1 异步任务
- 在springboot项目中使用以下2个注解可以省去写多线程来异步执行任务
在service方法上使用@Async,给spring定义此方法为异步方法
在启动类使用@EnableAsync,启用 Spring 的异步方法执行功能
- service
@Service
public class UserService {
//给spring定义此方法为异步方法
@Async
public void getResult(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步方法-方法!");
}
}
- controller
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/getResult")
public String getResult(){
userService.getResult();
return "结果信息-ok!";
}
}
- 启动器
@SpringBootApplication
@EnableAsync //启用 Spring 的异步方法执行功能
public class AsynctaskApplication {
public static void main(String[] args) {
SpringApplication.run(AsynctaskApplication.class, args);
}
}
- 访问http://127.0.0.1:8080/getResult测试结果,会发现“异步方法-方法!”会在页面信息显示后5秒后打印在控制台
10.2 邮件任务
-
springboot邮件发送简化了web阶段java发送邮件的过程,java邮件发送请看邮件介绍和实现
-
导入依赖,这个依赖包含了java发送邮件的两个jar包;javax.mail、javax.activation
<!--邮件依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
- 然后分析源码MailSenderAutoConfiguration邮件自动配置类可得配置类@EnableConfigurationProperties(MailProperties.class),然后我们只需要按照MailProperties类中的信息,在配置文件中配置spring.mail所需信息即可
#发送方发送的邮箱
spring.mail.username=123154687912@qq.com
#发送方邮箱授权码
spring.mail.password=xxxxxxxxxxxxxx
#发送方邮件服务器地址
spring.mail.host=smtp.qq.com
#qq邮箱需开启ssl加密
spring.mail.properties.mail.smtp.ssl.enable=true
- 测试,简单邮件发送
package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import javax.activation.FileDataSource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
@SpringBootTest
class AsynctaskApplicationTests {
@Autowired
JavaMailSenderImpl javaMailSender;
@Test
void contextLoads() {
//简单邮件
SimpleMailMessage message = new SimpleMailMessage();
message.setTo("a5@163.com");
message.setFrom("b@qq.com");
message.setSubject("邮件主题是啥呢?");
message.setText("简单邮件内容无标签格式");
javaMailSender.send(message);
}
}
- 复杂邮件发送
@Test
void contextFixMail() {
//复杂邮件
MimeMessage message = javaMailSender.createMimeMessage();
try {
MimeMessageHelper messageHelper = new MimeMessageHelper(message, true, "utf-8");
messageHelper.setTo("a@163.com");
messageHelper.setFrom("b@qq.com");
messageHelper.setSubject("复杂邮件主题是啥呢?");
messageHelper.setText("<p style='color: chocolate'>这是一封带<img src='cid:dec.jpg' alt='dec.jpg'>\\n图片的信件</p",true);
//messageHelper.addAttachment("dec",new FileDataSource("D:\\workspace_idea01\\springboot-shiro\\asynctask\\src\\main\\resources\\dec.jpg"));
messageHelper.addAttachment("dec",new FileDataSource("src/main/resources/dec.jpg"));
} catch (MessagingException e) {
e.printStackTrace();
}
javaMailSender.send(message);
}
- 工具封装
/**
* @param subject 主题
* @param html 支持html?
* @param text 文本内容
* @param pathname 图片、附件路径
* @param toAcc 发送账户
* @param fromAcc 源账户
* @Author zk
*/
@Test
void contextFixMailUtil(String subject,Boolean html,String text,String pathname,String toAcc,String fromAcc) {
//复杂邮件
MimeMessage message = javaMailSender.createMimeMessage();
try {
MimeMessageHelper messageHelper = new MimeMessageHelper(message, true, "utf-8");
messageHelper.setTo(toAcc);
messageHelper.setFrom(fromAcc);
messageHelper.setSubject(subject);
messageHelper.setText(text,html);
//messageHelper.addAttachment("dec",new FileDataSource("D:\\workspace_idea01\\springboot-shiro\\asynctask\\src\\main\\resources\\dec.jpg"));
messageHelper.addAttachment("dec",new FileDataSource(pathname));
} catch (MessagingException e) {
e.printStackTrace();
}
javaMailSender.send(message);
}
10.3 定时执行任务
- 计划任务,是任务在约定的时间执行已经计划好的工作
- 涉及的两个接口TaskExecutor任务执行和TaskScheduler任务调度
- 在启动类上加@EnableScheduling注解来开启定时任务
- @Scheduled:标记要计划的方法的注释。
@Scheduled:必须指定cron 、 fixedDelay或fixedRate属性之一。
带注释的方法必须没有参数。它通常有一个void返回类型;如果不是,则在通过调度程序调用时将忽略返回的值
- cron表达式:是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:
- Seconds Minutes Hours DayofMonth Month DayofWeek Year
- Seconds Minutes Hours DayofMonth Month DayofWeek
- 每一个域可出现的字符如下:
Seconds:可出现”, – * /”四个字符,有效范围为0-59的整数
Minutes:可出现”, – * /”四个字符,有效范围为0-59的整数
Hours:可出现”, – * /”四个字符,有效范围为0-23的整数
DayofMonth:可出现”, – * / ? L W C”八个字符,有效范围为0-31的整数
Month:可出现”, – * /”四个字符,有效范围为1-12的整数或JAN-DEC
DayofWeek:可出现”, – * / ? L C #”八个字符,有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一, 依次类推
Year:可出现”, – * /”四个字符,有效范围为1970-2099年
- 每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:
(1)`:表示匹配该域的任意值,假如在Minutes域使用, 即表示每分钟都会触发事件。
(2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用
*,如果使用
*表示不管星期几都会触发,实际上并不是这样。(3)-:表示范围,例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次
(4)/:表示数值的增量,简单来说,比如分写上0/5表示从0分开始,每隔5分钟
(5),:表示列出枚举值值。例如:在Minutes域使用5,20,则意味着在第5和第20分钟分别触发一次。
(6)L:表示最后,只能出现在DayofWeek和DayofMonth域,如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。
(7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份
(8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个非周六周末的日期。
(9)#:用于确定每个月第几个星期几,只能出现在DayofWeek域。例如在4#2,表示某月的第二个星期三。
(10)C 指和calendar联系后计算过的值。例:在day-of-month 字段用“5C”指在这个月第5天或之后包括calendar的第一天;在day-of-week字段用“1C”指在这周日或之后包括calendar的第一天。
- 举些个例子:
0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业
0 15 10 ? * 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作业
0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
0 * 14 * * ?” 在每天下午2点到下午2:59期间的每1分钟触发
0 0/5 14,18 * * ?” 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
0 0-5 14 * * ?” 在每天下午2点到下午2:05期间的每1分钟触发
0 15 10 L * ?” 每月最后一日的上午10:15触发
0 15 10 ? * 6#3″ 每月的第三个星期五上午10:15触发
- 测试,启动程序
@Service
public class ScheduledService {
//在一个特定的时间执行这个方法 也可以用Timer
@Scheduled(cron = "0 * * * * ?")
public void cronTime(){
System.out.println("定时任务执行!");
}
}
- 结果
下一篇:SpringBoot-36-分布式理论概述
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123836.html