SpringBoot异步任务

Posted 前度吖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot异步任务相关的知识,希望对你有一定的参考价值。

简介

场景1 当用户在前台页面使用邮件发送功能,这个请求会交于后端处理,如果采用同步任务,在这段时间内,前台的页面都是等待状态的,用户还会以为卡死,耗费时间和资源。

场景2用户上传Excel表格,后端需要先解析并且插入到数据库中,这个任务量是巨大的,所以这些均需要做异步处理。

......

以上这些场景使用多线程也是能解决的,这里简单记录一下,springBoot的异步使用方式。

异步任务

在SpringBoot中开启异步任务很简单,两个注解搞定 @EnableAsyncAsync。这里简单写个案例

1、需要执行的异步方法

    @Async  //方法加上这个注解,SpringBoot会开启一个新的线程来处理,也就不会有白屏等待时间
    public void insertExcel() {
        // 假如这个方法中执行一段耗时的逻辑代码 比如excel表格的读取与插入
        // 这里使用线程休眠来模拟,执行到这里,前台会白屏5秒
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("数据正在处理中...");
    }

2、启动类开启异步注解功能

@EnableAsync  //开启异步注解
@SpringBootApplication
@MapperScan("com.qd.springboot.mapper")
public class SpringbootApplication {

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

执行此方法后,控制台会直接打印内容,而无需等待时间,就是这么的香~

邮件任务

发送邮件任务也是开发中经常使用的,在SpringBoot中也比较简单

1、导入依赖

 <!--jakarta.mail -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-mail</artifactId>
   <version>2.5.2</version>
</dependency>

2、查看官方配置类

3、调用的方法

4、配置邮箱部分,开启协议并且生成授权码

5、配置yml

spring:
  mail:
    username: 666@qq.com  # 邮箱号
    password:   					# 授权码
    host: smtp.qq.com     # 发送的服务器
    properties: {mail.smtp.ssl.enable:true}   # 开启安全验证 部分邮箱没有

6、简单邮箱实现

@SpringBootTest
public class Test1 {
    @Autowired
    private JavaMailSenderImpl mailSender;

  
     /**
     * 简单邮件
     */
    @Test
    public void sendMail01() {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setSubject("java邮件测试"); //主题
        message.setText("试搞一个ava的邮件发送测试,你能猜出我是谁吗???"); //内容
        message.setTo("666@qq.com"); //接收人,是一个可变参数
        message.setFrom("666@qq.com"); // 发送者,必须与配置文件中一致
        message.setTo();
        mailSender.send(message);
    }
  
      /**
     * 复杂邮件
     */
    @Test
    public void sendMail02() throws MessagingException {
        // 可以直接传入文件
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");
        helper.setSubject("java邮件测试");
        String content = "内容";
        helper.setText("<div style=\'width: 100%;min-height: 250px;background-color: rgb(227,242,253);\'> <h2 style=\'text-align: center;color: rgb(187, 70, 70);\'>xxx服务邮件通知</h2><div style=\'width: 100%;min-height: 150px;margin: 20px 0px;background-color: white;\'><h3>尊敬的用户:</h3> <p style=\'padding: 0px 20px;\'>" + content + "</p><p style=\'padding: 0px 20px;\'>此致(本邮件由程序自动发送,您无需回复)</p></div><footer style=\'text-align: center;color: rgb(92, 96, 99);\'><a href=\\"#\\">xxxx公司</a></footer></div>\\n", true);
//        helper.addAttachment("附件名",new File("附件地址"));
        helper.setTo("666@qq.com");
        helper.setFrom("666@qq.com");
        mailSender.send(message);
    }
}

ps:为了方便开发可以抽取成为工具类

定时任务

在日常项目运行中,我们总会有需求在某一时间段周期性的执行某个动作。比如每天在某个时间段导出报表,或者每隔多久统计一次现在在线的用户量等。

在Spring Boot 中有Java自带的java.util.Timer类,也有强大的调度器Quartz,还有SpringBoot 自带的Scheduled 来实现。Scheduled在Spring5.引入,默认SpringBoot 自带该功能,使用起来也很简单,在启动类级别添加@EnableScheduling注解即可引入定时任务环境,但遗憾的是Scheduled 默认不支持分布式环境,这里简单测试下。

1、开启注解支持

@EnableScheduling // 开启注解支持
@SpringBootApplication
@MapperScan("com.qd.springboot.mapper")
public class SpringbootApplication {

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

2、cron表达式

// cron表达式
// cron = "0 * * * * 0-7"
// 秒 分 时 日 月 周几

在定时任务中,离不开这个表达式,不太好理解但是没关系 使用在线生成器 在线Cron表达式生成器

3、使用

@Service
public class ScheduledService {
  
    /**
     * 定时执行任务
     * 每天的0点30分会自动执行
     */
    @Scheduled(cron = "30 0 0 * * * *")
    public void hello(){
        System.out.println("在一个特定的时间里执行这个方法");
    }
}

使用起来特别的简单,但是如果你的项目是分布式的话,你可以使用Quartz这个框架来执行,在SpringBoot整合中也有提到过。

以上是关于SpringBoot异步任务的主要内容,如果未能解决你的问题,请参考以下文章

屏幕方向期间片段内的异步任务

#yyds干货盘点# springboot配置@Async异步任务的线程池

从片段中调用分离的异步任务类

Android 我应该在异步任务中将片段作为弱引用传递吗?

异步任务片段背景数据

我应该在 Fragment 中的啥生命周期状态下执行异步任务?