下一篇:20. Springboot+Dubbo+Zookeeper
1. 异步任务
-
创建一个service包,创建一个类AsyncService
异步处理还是非常常用的,比如我们在网站上发送邮件,后台会去发送邮件,此时前台会造成响应不动,直到邮件发送完毕,响应才会成功,所以我们一般会采用多线程的方式去处理这些任务
编写方法,假装正在处理数据,使用线程设置一些延时,模拟同步等待的情况;
@Service public class AsyncService { public void hello(){ try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("业务进行中...."); } }
-
编写controller包,编写AsyncController类
去写一个Controller测试一下
@RestController public class AsyncController { @Autowired AsyncService asyncService; @GetMapping("/hello") public String hello(){ asyncService.hello(); return "success"; } }
-
访问http://localhost:8080/hello进行测试,3秒后出现success,这是同步等待的情况
- 问题
我们如果想让用户直接得到消息,就在后台使用多线程的方式进行处理即可,但是每次都需要自己手动去编写多线程的实现的话,太麻烦了,我们只需要用一个简单的办法,在我们的方法上加一个简单的注解即可,如下
-
给hello方法添加
@Async
注解//告诉Spring这是一个异步方法 @Async public void hello(){ try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("业务进行中...."); }
SpringBoot就会自己开一个线程池,进行调用!但是要让这个注解生效,我们还需要在主程序上添加一个注解
@EnableAsync
,开启异步注解功能
- 重启测试,网页瞬间响应,3 s 后控制台输出“ 业务进行中…”
2. 定时任务
1. 概述
项目开发中经常需要执行一些定时任务,比如需要在每天凌晨的时候,分析一次前一天的日志信息,Spring为我们提供了异步执行任务调度的方式,提供了:
- 两个接口
-
TaskExecutor接口,任务执行
-
TaskScheduler接口,任务调度
- 两个注解:
- @EnableScheduling
开启异步任务调度 - @Scheduled
表示什么时候执行
- cron表达式
- 用到了六/七个
*
占位符,每个*
用一个空格隔开 ——* * * * * *
- 这六/七个
*
从前到后分别表示 —— 秒、分、时、日、月、周几 [、年] - 举例 :【 0 * * * * 1-7】
周一到周日的、任何月、任何日、任何时、任何分的、第 0 秒 执行操作 - 注:年可以省略,但是要写年必须要写到第七位
- 更详细的内容:cron表达式详解(也可自行百度)
- Cron表达式生成器
2. 使用
-
创建一个ScheduledService
我们里面存在一个hello方法,他需要定时执行,怎么处理呢?
@Service public class ScheduledService { @Scheduled(cron = "0 * * * * 0-7") public void hello(){ System.out.println("hello....."); } }
-
这里写完定时任务之后,我们需要在主程序上增加@EnableScheduling 开启定时任务功能
@EnableAsync //开启异步注解功能 @EnableScheduling //开启基于注解的定时任务 @SpringBootApplication public class SpringbootTaskApplication { public static void main(String[] args) { SpringApplication.run(SpringbootTaskApplication.class, args); } }
-
测试
在第 0 秒时,控制台输出了 ”hello…“
3. 邮件任务
邮件发送,在我们的日常开发中,也非常的多,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>
看它引入的依赖,可以看到 jakarta.mail 邮件发送
-
查看自动配置类
MailSenderAutoConfiguration
MailSenderJndiConfiguration
中存在mailSender
发送邮件的实现类,直接使用即可
去看下
MailProperties
配置文件
-
开始配置文件
spring.mail.username=123456@qq.com spring.mail.password=你的qq授权码 spring.mail.host=smtp.qq.com # qq需要配置ssl spring.mail.properties.mail.smtp.ssl.enable=true
获取授权码:在QQ邮箱中的设置->账户->开启pop3和smtp服务
-
Spring单元测试
1、 一个简单的邮件
@Autowired JavaMailSenderImpl mailSender; @Test public void contextLoads() { SimpleMailMessage message = new SimpleMailMessage(); // 设置邮件标题 message.setSubject("通知-开会"); // 设置邮件内容 message.setText("今晚7:30开会"); // 设置邮件收信人 message.setTo("123456@qq.com"); // 设置邮件发信人 message.setFrom("123456@qq.com"); // 发送 mailSender.send(message); }
2、 多文件组合、复杂的邮件
@Test public void contextLoads2() throws MessagingException { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, "UTF-8"); // 组装 // 设置邮件标题 message.setSubject("通知-开会"); // 设置邮件内容, 设为 true ,开启解析 HTML 标签功能 message.setText("<b style='color:red'>今天 7:30来开会</b>",true); // 添加附件 message.addAttachment("382824445_huge(1).jpg", new File("C:\\Users\\chenyuan\\Pictures\\Camera Roll\\382824445_huge(1).jpg")); // 设置邮件收信人 message.setTo("123456@qq.com"); // 设置邮件发信人 message.setFrom("123456@qq.com"); // 发送 mailSender.send(mimeMessage); }
-
查看邮箱,邮件接收成功
1、
2、 -
最后可以把上面的方法写成一个简单的工具类(仅仅演示,不完善)
/** * 把上面的方法封装成工具类 * @param multipart 是否开启 mimeMessage * @param encoding 字符编码 * @param subject 邮件标题 * @param text 邮件内容 * @param html 是否开启解析 HTML 标签功能 * @param attachmentFilename 附件名 * @param file 附件文件 * @param to 收件人邮箱 * @param from 发送者邮箱 * @throws MessagingException */ public void sendMail(boolean multipart, @Nullable String encoding, String subject, String text, boolean html, String attachmentFilename, File file, String to, String from) throws MessagingException { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper message = new MimeMessageHelper(mimeMessage, multipart, encoding); // 组装 // 设置邮件标题 message.setSubject(subject); // 设置邮件内容, 设为 true ,开启解析 HTML 标签功能 message.setText(text,html); // 添加附件 message.addAttachment(attachmentFilename, file); // 设置邮件收信人 message.setTo(to); // 设置邮件发信人 message.setFrom(from); // 发送 mailSender.send(mimeMessage); }
我们只需要使用Thymeleaf进行前后端结合即可开发自己网站邮件收发功能了!