• SpringBoot学习笔记(九)


    本文主要介绍SpringBoot:异步、定时、邮件任务的实现

    SpringBoot:异步、定时、邮件任务

    前言:

    异步任务举例:发送邮件,后台在发送邮件时,任务执行完毕,才显示发送成功的消息给用户,有可能因为一点点延迟而影响用户体验,所以采用多线程的方式处理。
    定时任务举例:需要在某个时间点查看日志信息。
    邮件任务举例:QQ邮箱发邮件。

    • SpringBoot:异步任务

    1、在service包下,创建一个类AsyncService

    image

    package com.zhou.service;
    
    import org.springframework.stereotype.Service;
    
    //编写方法,假装正在处理数据,使用线程设置一些延时,模拟同步等待的情况
    @Service
    public class AsyncService {
    
        public  void send(){
            System.out.println("业务正在进行中....");
            try {
                Thread.sleep(7000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    2.在controller包下,编写AsyncController类

    image

    package com.zhou.controller;
    
    import com.zhou.service.AsyncService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class AsyncController {
        @Autowired
        AsyncService asyncService;
    
        @GetMapping("/h1")
        public String hello(){
    
            asyncService.send();
            return "邮件收到啦";
        }
    }
    

    3.访问:http://localhost:8081/h1 ,7秒后出现邮件收到啦,这是同步等待的情况

    image

    利用多线程,可以异步给给用户先反馈消息。但是,每次需要单独处理,有点麻烦。现在在SpringBoot中,只需要添加一个注解:@Async

    4.给send()方法添加@Async注解(SpringBoot就会自己开一个线程池,进行调用)

    package com.zhou.service;
    
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.stereotype.Service;
    
    //编写方法,假装正在处理数据,使用线程设置一些延时,模拟同步等待的情况
    @Service
    public class AsyncService {
        //告诉Spring这是一个异步方法
        @Async
        public  void send(){
            System.out.println("业务正在进行中....");
            try {
                Thread.sleep(7000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    5.在主程序上添加一个注解 @EnableAsync,开启异步注解功能;

    package com.zhou;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.scheduling.annotation.EnableAsync;
    
    @EnableAsync //开启异步注解功能
    @SpringBootApplication
    public class SpringbootSwaggerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringbootSwaggerApplication.class, args);
        }
    
    }
    

    6.访问:http://localhost:8081/h1 页面瞬间响应邮件收到啦


    • SpringBoot:定时任务

    Spring为我们提供了异步执行任务调度的方式,提供了

    两个接口:

    TaskExecutor接口
    TaskScheduler接口
    

    两个注解:

    @EnableScheduling
    @Scheduled
    
    • cron表达式:

    cron:计划任务,是任务在约定的时间执行已经计划好的工作,这是表面的意思。在Linux中,我们经常用到 cron 服务器来完成这项工作。cron服务器可以根据配置文件约定的时间来执行特定的任务。

    在线Cron表达式生成器

    cron字段释义:

    0 0/5 * * * ?
    秒 分 时 天(月) 月 天(周) 年份(一般省略)
    

    cron符号释义:

    image

    cron应用的部分案例:

    image

    • 测试,使用:

    1、创建 ScheduledService

    package com.zhou.service;
    
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Service;
    
    @Service
    public class ScheduledService {
        //注意cron表达式的用法;
        @Scheduled(cron = "0/2 * * * * ?")
        public void hello(){
            System.out.println("Hi,我来了");
        }
    }
    

    2.在主程序上增加@EnableScheduling 开启定时任务功能

    package com.zhou;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.scheduling.annotation.EnableScheduling;
    
    @EnableScheduling
    @EnableAsync //开启异步注解功能
    @SpringBootApplication//开启基于注解的定时任务
    public class SpringbootSwaggerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringbootSwaggerApplication.class, args);
        }
    }
    
    1. Run 启动:

    image

    • cron 常用表达式
    (1)0/2 * * * * ? 表示每2秒 执行任务
    
    (1)0 0/2 * * * ? 表示每2分钟 执行任务
    
    (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触发
    

    • SpringBoot:邮件任务

    Springboot 支持邮件发送

    1.引入spring-boot-start-mail

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

    在pom中,Ctrl+spring-boot-starter-mail 点进来,看到spring-boot-starter-mail 引入的依赖

    image

    2.查看自动配置类:MailSenderAutoConfiguration

    image

    3.在 MailSenderJndiConfiguration 类中,找到了Bean JavaMailSenderImpl

    image

    4.查看 MailProperties 配置文件

    image

    5.开始,配置邮件发送功能吧

    image

    server.port=8081
    
    spring.mail.username=16xxxxx889@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服务

    image

    6.Spring单元测试

    package com.zhou;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.core.io.FileSystemResource;
    import org.springframework.mail.SimpleMailMessage;
    import org.springframework.mail.javamail.JavaMailSender;
    import org.springframework.mail.javamail.MimeMessageHelper;
    
    import javax.mail.MessagingException;
    import javax.mail.internet.MimeMessage;
    import java.io.File;
    
    @SpringBootTest
    class SpringbootSwaggerApplicationTests {
    
        @Autowired
        JavaMailSender javaMailSender;
        //邮件设置1:一个简单的邮件
        @Test
        void contextLoads() {
            SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
            simpleMailMessage.setSubject("一个简单的邮件");
            simpleMailMessage.setText("你会用SpringBoot发送邮件吗?");
    
            simpleMailMessage.setTo("16xxxxx889@qq.com");//邮箱
            simpleMailMessage.setFrom("16xxxxx889@qq.com");//邮箱
    
            javaMailSender.send(simpleMailMessage);
    
        }
        //邮件设置2:一个比较复杂的邮件
        @Test
        void contextLoads2() {
            //桌面上放了两个图片
            String [] fileArray={"C:\Users\16939\Desktop\springboot1.jpg","C:\Users\16939\Desktop\springboot2.jpg"};
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = null;
            try {
                mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
    
                mimeMessageHelper.setSubject("一个复杂的邮件");
                mimeMessageHelper.setText("你会用SpringBoot 发送一个比较复杂的邮件吗?");
                mimeMessageHelper.setTo("16xxxxx889@qq.com");//邮箱
                mimeMessageHelper.setFrom("16xxxxx889@qq.com");//邮箱
    
                if(fileArray!=null){
                    FileSystemResource fileSystemResource=null;
                    for (int i = 0; i < fileArray.length; i++) {
                        //添加附件
                         fileSystemResource=new FileSystemResource(fileArray[i]);
                         mimeMessageHelper.addAttachment(fileArray[i].substring(fileArray[i].lastIndexOf(File.separator)),fileSystemResource);
                    }
                }
                javaMailSender.send(mimeMessage);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    可能报错:Caused by: com.sun.mail.smtp.SMTPSenderFailedException: 501 Mail from address must be same as authorization user.

    image

    解决:确定邮箱地址的正确性!

    7.查看邮箱:

    image

    image

    Ok!(记得关闭qq邮箱的授权码功能,用的时候再开启)

    image

    个人学习笔记,针对本人在自学中遇到的问题。

  • 相关阅读:
    JavaScript 基础(三)
    2015-10-15 第十四节课 补充CSS一些特殊选择器
    2015-09-29 第八节课 JavaScript 基础(二)(js语句:条件、循环)
    2015-09-28 第七节课JavaScript 基础(一) (js简介、声明变量、数据类型)
    2015 09-23 第五节课程(css:仿站及常见代码用法)
    【小练习2】如何制作“表格”
    51nod-1627 瞬间移动(组合数+逆元)
    POJ-3450 Corporate Identity (KMP+后缀数组)
    POJ-2406 Power Strings(KMP)
    CSU-1632 Repeated Substrings (后缀数组)
  • 原文地址:https://www.cnblogs.com/1693977889zz/p/14575286.html
Copyright © 2020-2023  润新知