SpringBoot从入门到精通—SpringBoot异步任务、定时服务和邮件服务

1、SpringBoot—异步任务

    异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步程序执行完即可执行。
    实现异步处理任务的方式有很多,我们可以自己通过多线程来实现或者也可以使用SpringBoot提供的@EableAysnc@Aysnc这两个注解来实现。

1.1 通过多线程来实现异步处理任务

直接在需要异步任务处理的方法中开启新的线程来处理任务。

@Service
public class AsyncService {

    private Logger log= LoggerFactory.getLogger(AsyncService.class);

   /**
     * 手动开启一个线程来处理异步任务
     */
    public void async(){
        log.info("开始处理任务");
        //开启一个新新线程方式来异步处理任务
        new Thread(() -> {
            try {
                log.info("处理中,请稍等...");
                Thread.sleep(3000);   //处理过程中
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        log.info("任务提前返回,交给另一个线程处理");
    }
}

执行结果如下:

1.2 使用SpringBoot提供的注解处理异步任务

首先在需要异步任务处理的方法上加上@Async注解告诉SpringBoot这个方法需要异步处理

@Service
public class AsyncService {

    private Logger log= LoggerFactory.getLogger(AsyncService.class);

    @Async    //开启异步任务
    public void async(){
       log.info("开始处理");
        try {
            log.info("处理中,请稍等...");
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("处理完成.....");
    }

}

然后在主配置类使用@EnableAsync注解开启异步注解功能

package com.xust.iot.task;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync    //开启异步注解功能
@SpringBootApplication
public class SpringBootTaskApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootTaskApplication.class, args);
    }
}

执行结果如下,SpringBoot也是开启了一个新的线程task-1来处理这个任务的:

2、SpringBoot—定时任务

定时任务就是提前设置好时间点,然后每到这个时间点就会执行的任务。SpringBoot中可以通过@Scheduled@EableScheduled这两个注解来实现定时任务。
同样在需要定时任务对方法上标注@Scheduled注解,然后在主配置类上标注@EableScheduled注解开启定时注解功能

@Service
public class ScheduledService {

    private Logger log= LoggerFactory.getLogger(ScheduledService.class);

    //0  *  *  *  *  MON-FRI
    //秒 分 时 日 月  星期
    @Scheduled(cron="0 * * * * 1-7")     //星期一~星期天 每分钟的整秒(00秒)执行该任务
    public void service1(){
        log.info("执行定时任务service1@"+ LocalDateTime.now());
    }

    @Scheduled(cron="1,11,21,31,41,51 * * * * 1-7")  //星期一~星期天  每分钟的1秒,11秒,21秒,31秒,41秒,51秒的时候执行该任务
    public void service2(){
        log.info("执行定时任务service2@"+ LocalDateTime.now());
    }

    @Scheduled(cron = "0-5 * * * * 1-7")   //星期一~星期天  每分钟的00秒~05秒执行该任务
    public void service3(){
        log.info("执行定时任务service3@"+ LocalDateTime.now());
    }

    @Scheduled(cron = "0/5 * * * * 1-7")    //星期一~星期天  从00秒开始每隔5秒执行该任务
    public void service4(){
        log.info("执行定时任务service4@"+ LocalDateTime.now());
    }
}

执行结果:

从上面这个例子中可以看到,对于定时任务使用主要就是对cron表达式的编写,cron允许的值可以有以下几种:

字段允许值允许的特殊字符
0-59, - * /
0-59, - * /
小时0-23, - * /
1-31, - * / ? L W C
1-12, - * /
星期0-7或SUN-STA, - * / ? L W C #
解释: > , :表示枚举,可以用它在一个一段上枚举多个值 — :表示一个区间
* :表示任意
/ :步长 ?:日/星期冲突匹配 L : 最后 W: 工作日 C : 和Calendar联系后计算后的值
# :星期,例如4#2 表示第二个星期四

下面是几个用法示例:

@Service
public class ScheduledService {

    private Logger log= LoggerFactory.getLogger(ScheduledService.class);

    @Scheduled(cron="0 0/5 14,18 * * ?")  //每天14点整合18点整,每隔5分钟执行一次该任务
    public void service5(){
        log.info("执行定时任务service5@"+ LocalDateTime.now());
    }

    @Scheduled(cron="0 30 12 ? * 1-6")  //每月的周一~周六12:30执行一次该任务
    public void service6(){
        log.info("执行定时任务service6@"+ LocalDateTime.now());
    }

    @Scheduled(cron = "0 0 12 ? * 6L")  //每月的最后一个周六中午12点执行一次
    public void service7(){
        log.info("执行定时任务service7@"+ LocalDateTime.now());
    }

    @Scheduled(cron = "0 0 12 LW * ?")   //每月的最后一个工作日的12点执行一次
    public void service8(){
        log.info("执行定时任务service8@"+ LocalDateTime.now());
    }

    @Scheduled(cron = "0 0 6/1 ? * 4#2")   //每月的第二个星期四在六点整开始每隔一小时执行一次
    public void service9(){
        log.info("执行定时任务service9@"+ LocalDateTime.now());
    }

}

3、SpringBoot—邮件任务

       Spring Email 抽象的核心是 MailSender 接口,MailSender 的实现能够把 Email 发送给邮件服务器,由邮件服务器实现邮件发送的功能。

       Spring 自带了一个 MailSender 的实现 JavaMailSenderImpl,它会使用 JavaMail API 来发送 Email。Spring 或 SpringBoot 应用在发送 Email 之前,我们必须要 JavaMailSenderImpl 装配为 Spring应用上下文的一个 bean。
3.1 首先引入邮件服务的starter
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
3.2 邮件配置
spring:
  mail:
    host: smtp.qq.com            #smpt主机
    password: ceozdvepgtlydihg   #这里的password是生成的授权码,不是账户密码
    username: huangxin9830@qq.com
    properties:
      mail.smpt.ssl: true       #设置使用SSL安全协议
3.3 简单邮件服务—SimpleMessage

使用简单邮件服务只能发送文本消息

    @Autowired
    JavaMailSenderImpl mailSender;

    @Test
    public void contextLoads() {
        //简单邮件服务
        SimpleMailMessage message = new SimpleMailMessage();

        message.setSubject("你好,这是SpringBootMail");
        message.setFrom("2489868503@qq.com");
        message.setText("Hello JMail!");
        message.setTo("2489868503hx@gmail.com");
        mailSender.send(message);
    }

执行的结果,成功收到了邮件:

3.4 复杂邮件服务—MimeMessage

使用复杂邮件服务可以发送文本消息、HTML语句、甚至支持上传附件

 @Test
    public void test02(){
        //复杂邮件服务
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setSubject("你好,陌生人!");
            helper.setFrom("2489868503@qq.com");
             //HTML语句  
            helper.setText("<font color='red'>你中奖啦!!!</font>",true);
            helper.setTo("2489868503hx@gmail.com");
            //上传附件
            helper.addAttachment("1.jpg",new File("D:\\pic\\1.jpg"));
            helper.addAttachment("2.jpg",new File("D:\\pic\\2.jpg"));
        } catch (MessagingException e) {
            e.printStackTrace();
        }
       mailSender.send(mimeMessage);
    }

执行结果:在GMail收到了邮件,并且设置HTML样式起作用了,附件也上传成功了。

留言区

还能输入500个字符