SpringBoot(十) 异步任务,定时任务和邮件任务

异步任务

“异步调用”对应的是“同步调用”,同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行;异步调用指程序在顺序执行时,不等待异步调用的语句返回结果就执行后面的程序。

@Service
public class AsyncService {


    public void testTask(){
        try{
            Thread.sleep(3000);
        }catch (Exception e){

        }
        System.out.println("哈哈哈哈");
    }
}

上述的同步调用虽然顺利的执行完了,可以并发执行的话,同步调用在执行效率方面就比较差,可以考虑通过异步调用的方式来并发执行。

在Spring Boot中,我们只需要通过使用@Async注解就能简单的将原来的同步函数变为异步函数,主类改在为如下模式:

@EnableAsync //开启异步注解
@SpringBootApplication
public class DemoApplication {

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

service修改如下,加上@Async注解,就能有效的减少了程序的总运行时间。

@Service
public class AsyncService {

    @Async  //注解
    public void testTask(){
        try{
            Thread.sleep(3000);
        }catch (Exception e){

        }
        System.out.println("哈哈哈哈");
    }
}

注: @Async所修饰的函数不要定义为static类型,这样异步调用不会生效。

定时任务

在编写Spring Boot应用中经常会遇到这样的场景,比如:我需要定时地发送一些短信、邮件之类的操作,也可能会定时地检查和监控一些标志、参数等。

1.编写主程序

@EnableAsync //开启异步注解
@EnableScheduling //开启定时注解
@SpringBootApplication
public class DemoApplication {

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

 2.编写测试类

@Service
public class ScheduledService {

    /**
     * 指定定时任务的表达式
     * second(秒),minute(分),hour(日),day of month(日),month(月),day of week(周几)。空格隔开
     */

    //每5秒走一次
    @Scheduled(cron = "*/5 * * * * *")
    public void hello(){
        System.out.println("hello");
    }
}
  • @Scheduled(fixedRate = 5000) :上一次开始执行时间点之后5秒再执行
  • @Scheduled(fixedDelay = 5000) :上一次执行完毕时间点之后5秒再执行
  • @Scheduled(initialDelay=1000, fixedRate=5000) :第一次延迟1秒后执行
  • @Scheduled(cron="0/5 * * * * *") :通过cron表达式定义规则。0秒启动,每5秒启动一次

 

邮件任务

相信使用过Spring的众多开发者都知道Spring提供了非常好用的JavaMailSender接口实现邮件发送。

在Spring Boot的Starter模块中也为此提供了自动化配置。

1.在pom.xml中引入依赖

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

如其他自动化配置模块一样,在完成了依赖引入之后,只需要在application.properties中配置相应的属性内容。

2.以QQ邮箱为例,在application.properties中加入如下配置(注意替换自己的用户名和密码):

spring.mail.host=smtp.qq.com
spring.mail.username=用户名
spring.mail.password=密码
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

3.编写测试类

@Service
public class ScheduledService {

    @Autowired
    JavaMailSenderImpl javaMailSender;

    public void sendMail(){
        SimpleMailMessage message = new SimpleMailMessage();

        //邮件设置  标题
        message.setSubject("你猜");
        //内容
        message.setText("你猜我是谁");
        //收件人
        message.setTo("");
        //发件人
        message.setFrom("");

        javaMailSender.send(message);
    }
}

 到这里,一个简单的邮件发送就完成了.

MimeMessage

上面是通过使用SimpleMailMessage实现了简单的邮件发送,但是实际使用过程中,我们还可能会带上附件、或是使用邮件模块等。这个时候我们就需要使用MimeMessage来设置复杂一些的邮件内容。

    public void sendMail02() throws MessagingException {

        //创建一个复杂邮件
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();

        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);

        //邮件设置  标题
        helper.setSubject("你猜");
        //内容 可以兼容html片段
        helper.setText("<b>你猜我是谁</b>");
        //参数2:  解析HTML
        helper.setText("<html><body><img src=\"cid:weixin\" ></body></html>", true);

        //上传附件   参数1:名称  参数2:文件
        helper.addAttachment("1.jpg",new File(""));
        //收件人
        helper.setTo("");
        //发件人
        helper.setFrom("");

        javaMailSender.send(mimeMessage);
    }