springboot定时-邮件-异步


title: springboot定时-邮件-异步
date: 2020-08-20 18:44:32
tags: [‘框架’]


介绍: 以前我们想要异步处理一个请求,还需要我们手动去创建线程池去执行,我们要开启定时任务也是很复杂的,还有发送邮件…springboot的出现让这一切变得简单,只需要简单的配置就可以实现。但是我们想要真整的了解和掌握这些技术,还是需要我们比零开始一步步的搭建,才能真的做到活学活用。

springboot异步-定时-邮件

1、定时任务

(1)了解cron表达式

定时任务在我们开发中也是比较常见的,数据定时清楚了,更新之类的,我们通过cron表达式定义定时任务的执规则。

cron表达式: 秒 分 时 日 月 星期 年

(1)* 表示匹配该域的任意值

(2)- : 表示范围

(3)?: 只能用在DayofMonth和DayofWeek两个域。 因为日期和星期有冲突,假如我们要10号触发,肯定就不用考虑是星期几个,但是*是匹配所有,因此要用**?符号**

(4)/ : 表示开始时间,每隔多久执行一次。 例如Minutes 使用5/20,则意味着20分钟触发一次

(5)L : 表示最后,只能出现在DayofWeek和DayofMonth域

(6)W : 表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件

(7)LW : 表示在某个月最后一个工作日,即最后一个星期五

(8)# : 用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三

(9),: 表示并列,枚举的意思

在开发中我们为了避免出错,我们可以使用在线成功工具:cron在线生成工具

了解了cron表达式,我们就可以开启定时任务了。

(2)代码操作

1、在springboot的启动类上加入注解:@EnableScheduling

2、创建定时任务类

@Component                              //要交给spring容器管理
public class SecdulingConfig {
    private static Logger logger=LoggerFactory.getLogger(SecdulingConfig.class);
    @Scheduled(cron = "0/3 * * * * ? ") //定时执行方法 ,cron表达式,每3秒执行一次
    public void say(){
        logger.info("我来了");

    }
}

3、启动程序结果打印

2020-08-21 10:48:09.001  INFO 9876 --- [boot-Scheduled1] com.dl.config.SecdulingConfig            : 我来了
2020-08-21 10:48:12.001  INFO 9876 --- [boot-Scheduled1] com.dl.config.SecdulingConfig            : 我来了
2020-08-21 10:48:15.002  INFO 9876 --- [boot-Scheduled1] com.dl.config.SecdulingConfig            : 我来了
2020-08-21 10:48:18.001  INFO 9876 --- [boot-Scheduled1] com.dl.config.SecdulingConfig            : 我来了

每3秒就会打印一次,测试通过,我们在开启一个定时任务…

@Component
public class SecdulingConfig {
    private static Logger logger=LoggerFactory.getLogger(SecdulingConfig.class);
    @Scheduled(cron = "0/3 * * * * ? ")
    public void say(){
        logger.info("定时任务1");
        try{
            Thread.sleep(2000);  //模拟业务执行
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    @Scheduled(cron = "0/2 * * * * ? ")
    public void say2(){
        logger.info("定时任务2");
    }

}
2020-08-21 11:04:12.001  INFO 10580 --- [   scheduling-1] com.dl.config.SecdulingConfig            : 定时任务1
2020-08-21 11:04:14.002  INFO 10580 --- [   scheduling-1] com.dl.config.SecdulingConfig            : 定时任务2
2020-08-21 11:04:15.001  INFO 10580 --- [   scheduling-1] com.dl.config.SecdulingConfig            : 定时任务1
2020-08-21 11:04:17.002  INFO 10580 --- [   scheduling-1] com.dl.config.SecdulingConfig            : 定时任务2
2020-08-21 11:04:18.001  INFO 10580 --- [   scheduling-1] com.dl.config.SecdulingConfig            : 定时任务1

不难看出在执行这两个定时任务的时候,使用的是同一条线程,所以问题就出现了,两个定时任务之间会相互影响,导致不是在我们规定的时间执行的。

所以我们要修改定时任务的执行线程,我们使用线程池去执行定时任务,spring为我们提供了异步任务执行的接口,我们进行配置:

//用线程池去执行定时任务,在测试下成功
@Bean
    public TaskScheduler taskScheduler(){
        ThreadPoolTaskScheduler  tts=new ThreadPoolTaskScheduler();
        tts.setPoolSize(10);
        tts.setThreadNamePrefix("springboot-Scheduled");
        return  tts;
    }

2、邮件任务

随着网络的发展,邮件效验通知用户是越来越火爆。

(1)引入jar
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
(2)配置文件
spring.mail.host=smtp.qq.com
spring.mail.username=2415414232@qq.com
spring.mail.password=你的qq授权码
spring.mail.default-encoding=UTF-8
 #下面的部署要用
spring.mail.port=465
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

qq授权码在qq邮箱----设置----账号-----开启smtp服务–我们就可以获取我们的qq授权码了

(3)发送邮件
//springboot已经帮我们封装好了,直接导入
    @Autowired
    private JavaMailSenderImpl javaMailSender;
//发送简单邮件
public String sendSimpleMail() {
        try {
            SimpleMailMessage smm = new SimpleMailMessage();
            smm.setFrom("2415414232@qq.com");      //谁发的
            smm.setTo("766027826@qq.com"); //发给谁
            smm.setSubject("加油吧!");     //主题
            smm.setText("点击一下吧:" + "https://dl6hg.cn");
            javaMailSender.send(smm);  //邮件发送
        }catch (Exception e){
            e.printStackTrace();
            return "发送失败!";
        }
        return "发送成功!";
    }

766027826用户就可以收到我们发送的邮件了

//发送html邮件
 public String sendMimeMail() {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper=new MimeMessageHelper(mimeMessage,true);
            mimeMessageHelper.setFrom("2415414232@qq.com");
            mimeMessageHelper.setTo("766027826@qq.com");
            mimeMessageHelper.setSubject("这是文件");  //主体
            mimeMessageHelper.setText("<h1 style='color:red'>helloWorld</h1><img src='cid:test001'/>",true); //文本内容
            mimeMessageHelper.addInline("test001", new FileSystemResource(ResourceUtils.getFile("classpath:nuli2.jpg"))); //内容图片
            mimeMessageHelper.addAttachment("附件",new FileSystemResource(ResourceUtils.getFile("classpath:nuli2.jpg")));  //附件
            javaMailSender.send(mimeMessage);  //发送邮件
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "发送成功";
    }

邮件发送是非常慢的,不可能让用户一直在哪里等待,所以我们要异步处理,用户点击发送邮件,我们直接返回结果给用户,另一条线程去发送邮件,通常我们要创建线程池,但是现在springboot已经给我们提供好了。

3、异步任务

(1)开启异步
@EnableAsync                        // 开启异步
(2)业务层修改
//我们的controller层 
@RequestMapping("/aa")
    public   String  aa() {
        mailService.sendSimpleMail();   //调用业务层邮件发送方法
        return "发送成功";
    }

访问该衔接我们要好几秒才能看到发送成功,因为邮件发送需要很长时间,我们现在用多线程处理邮件发送,在service层方法上添加注解就可以实现异步,方便吧

@Async   //异步注解
   //springboot已经帮我们封装好了,直接导入
public String sendSimpleMail() {
        try {
            SimpleMailMessage smm = new SimpleMailMessage();
            smm.setFrom("2415414232@qq.com");      //谁发的
            smm.setTo("766027826@qq.com"); //发给谁
            smm.setSubject("加油吧!");     //主题
            smm.setText("点击一下吧:" + "https://dl6hg.cn");
            javaMailSender.send(smm);  //邮件发送
        }catch (Exception e){
            e.printStackTrace();
            return "发送失败!";
        }
        return "发送成功!";
    }

访问衔接,瞬间看到发送成功,这也是我们经常用短信登陆APP时,点击下获取验证码就看到发送成功,但是我们好久才可以正真的收到短信。

# 框架 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×