SpringBoot整合Quartz及异步调用的案例

 更新时间:2023年03月09日 15:45:09   投稿:mrr  
Quartz是一个完全由java编写的开源作业调度框架、它的简单易用受到业内人士的一致好评,这篇文章主要介绍了SpringBoot整合Quartz及异步调用,需要的朋友可以参考下

前言

Quartz是一个完全由java编写的开源作业调度框架、它的简单易用受到业内人士的一致好评。本篇记录怎么用SpringBoot使用Quartz

一、异步方法调用

由于多个任务同时执行时,默认为单线程,所以我们用异步方法调用,使其成为多线程执行

看一个案例

1、导入依赖

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

2、创建异步执行任务线程池

这里我们使用springboot自带的线程池

package com.lzl.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;


@Configuration
public class AsyncExcutorPoolConfig implements AsyncConfigurer {

    @Bean("asyncExecutor")
    @Override
    public Executor getAsyncExecutor() {
        //Spring自带的线程池(最常用)
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //线程:IO密集型 和 CPU密集型
        //线程设置参数
        taskExecutor.setCorePoolSize(8);//核心线程数,根据电脑的核数
        taskExecutor.setMaxPoolSize(16);//最大线程数一般为核心线程数的2倍
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);//任务执行完成后关闭

        return taskExecutor;
    }
}

注意注解不要少

3、创建业务层接口和实现类

package com.lzl.Service;

/**
 * --效率,是成功的核心关键--
 *
 * @Author lzl
 * @Date 2023/3/7 09:42
 */

public interface AsyncService {
    void testAsync1();

    void testAsync2();
}
package com.lzl.Service.impl;

import com.lzl.Service.AsyncService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * --效率,是成功的核心关键--
 *
 * @Author lzl
 * @Date 2023/3/7 09:43
 */
@Service
public class AsyncImpl implements AsyncService {
    @Async
    @Override
    public void testAsync1() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("精准是唯一重要的标准!");
    }

    @Async("asyncExecutor")//开启异步执行
    @Override
    public void testAsync2() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("效率是成功的核心关键!");
    }
}

4、创建业务层接口和实现类

package com.lzl.task;

import com.lzl.Service.AsyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * --效率,是成功的核心关键--
 *
 * @Author lzl
 * @Date 2023/3/7 09:40
 */
@RestController
@RequestMapping("/login")
public class LoginController {
    @Autowired
    private AsyncService service;

    @RequestMapping("/Async1")
    public String testAsync1(){
        service.testAsync1();
        return "牛逼!";
    }
    @RequestMapping("/Async2")
    public String testAsync2(){
        service.testAsync2();
        return "不牛逼!";
    }
}

在启动类开启异步

整体目录结构如下:

测试:
运行项目,访问controller

访问controller时,页面直接出现返回值,控制台过了两秒打印文字,证明异步执行成功!

二、测试定时任务

1.导入依赖

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

2.编写测试类,开启扫描定时任务

package com.lzl.task;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.Date;

/**
 * --效率,是成功的核心关键--
 *
 * @Author lzl
 * @Date 2023/3/7 10:42
 */
//任务类
@Configuration
public class Tasks {
    @Async
    @Scheduled(cron = "*/2 * * * * ?")
    public void task1(){
        System.out.println("效率"+new Date().toLocaleString());
    }
    @Async
    @Scheduled(cron = "*/1 * * * * ?")
    public void task2(){
        System.out.println("精准"+new Date().toLocaleString());
    }
}

3.测试

三、实现定时发送邮件案例

这里以QQ邮箱为例,这个功能类似于通过邮箱找回密码类似,需要我们进行授权码操作

1.邮箱开启IMAP服务

登陆QQ邮箱,找到帐户,下拉

看到如下图:

我这里已经开启了,按照步骤操作,会有一个授权码,保存好下边步骤要用,此处不再演示

2.导入依赖

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 邮箱 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

3.导入EmailUtil

package com.lzl.utils;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
import java.util.Random;
/**
 * --效率,是成功的核心关键--
 *
 * @Author lzl
 * @Date 2023/3/7 11:44
 */

public class EmailUtil {

    private static final String USER = "@qq.com"; // 发件人邮箱地址
    private static final String PASSWORD = ""; // qq邮箱的客户端授权码(需要发短信获取)

    /**
     * @param to    收件人邮箱地址
     * @param text  邮件正文
     * @param title 标题
     */
    /* 发送验证信息的邮件 */
    public static boolean sendMail(String to, String text, String title) {
        try {
            final Properties props = new Properties();
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.host", "smtp.qq.com");

            // 发件人的账号
            props.put("mail.user", USER);
            //发件人的密码
            props.put("mail.password", PASSWORD);

            // 构建授权信息,用于进行SMTP进行身份验证
            Authenticator authenticator = new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    // 用户名、密码
                    String userName = props.getProperty("mail.user");
                    String password = props.getProperty("mail.password");
                    return new PasswordAuthentication(userName, password);
                }
            };
            // 使用环境属性和授权信息,创建邮件会话
            Session mailSession = Session.getInstance(props, authenticator);
            // 创建邮件消息
            MimeMessage message = new MimeMessage(mailSession);
            // 设置发件人
            String username = props.getProperty("mail.user");
            InternetAddress form = new InternetAddress(username);
            message.setFrom(form);

            // 设置收件人
            InternetAddress toAddress = new InternetAddress(to);
            message.setRecipient(Message.RecipientType.TO, toAddress);

            // 设置邮件标题
            message.setSubject(title);

            // 设置邮件的内容体
            message.setContent(text, "text/html;charset=UTF-8");
            // 发送邮件
            Transport.send(message);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    //随机生成num个数字验证码
    public static String getValidateCode(int num) {

        Random random = new Random();
        String validateCode = "";
        for (int i = 0; i < num; i++) {
            //0 - 9 之间 随机生成 num 次
            int result = random.nextInt(10);
            validateCode += result;

        }
        return validateCode;
    }

    //测试
    public static void main(String[] args) throws Exception {
        //给指定邮箱发送邮件
        EmailUtil.sendMail("729953102@qq.com", "你好,这是一封测试邮件,无需回复。", "测试邮件随机生成的验证码是:" + getValidateCode(6));
        System.out.println("发送成功");

    }
}

4.编写邮件发送方法

package com.lzl.task;

import com.lzl.utils.EmailUtil;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;

/**
 * --效率,是成功的核心关键--
 *
 * @Author lzl
 * @Date 2023/3/7 11:45
 */
@Configuration
public class TaskEmail {
    //指定时间进行发送邮件
    @Scheduled(cron = "10 49 11 * * ?")
    public void sendMail(){
        EmailUtil.sendMail("自己的邮箱@qq.com", "效率,是成功的核心关键!", "测试邮件随机生成的验证码是:" + EmailUtil.getValidateCode(6));
    }
}

5.开启异步和定时任务

package com.lzl;

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


@SpringBootApplication
@EnableAsync//开启异步
@EnableScheduling//开启定时任务
public class QuartzStudyApplication {

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

}

测试:
此处不再演示

总结

定时任务在很多业务场景中经常会用到,好记性不如烂笔头,本篇只是简单的记录一下

到此这篇关于SpringBoot整合Quartz以及异步调用的文章就介绍到这了,更多相关SpringBoot整合Quartz内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解决SecureRandom.getInstanceStrong()引发的线程阻塞问题

    解决SecureRandom.getInstanceStrong()引发的线程阻塞问题

    这篇文章主要介绍了解决SecureRandom.getInstanceStrong()引发的线程阻塞问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java中使用阻塞队列控制线程集实例

    Java中使用阻塞队列控制线程集实例

    这篇文章主要介绍了Java控制阻塞队列线程集实例,本文用一个程序展示了如何使用阻塞队列来控制线程集,程序功能是在一个目录及它的所有子目录下搜索所有文件,打印出包含指定关键字的文件列表,需要的朋友可以参考下
    2015-01-01
  • java中&与&&的区别

    java中&与&&的区别

    本文主要介绍了java中&与&&的区别,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • Spring根据XML配置文件注入属性的方法

    Spring根据XML配置文件注入属性的方法

    下面小编就为大家带来一篇Spring根据XML配置文件注入属性的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • JVM知识总结之垃圾收集算法

    JVM知识总结之垃圾收集算法

    本博客为读书笔记,读的是《深入理解Java虚拟机》一书,在看这个书的时候,最大的一个感受便是“当初怎么就没有好好学习操作系统呢,不然也不会有这么多看的云里雾里的地方了”,不过那都是过去的事了,学习最好的时刻便是现在,需要的朋友可以参考下
    2021-06-06
  • Java interrupt()方法使用注意_动力节点Java学院整理

    Java interrupt()方法使用注意_动力节点Java学院整理

    这篇文章主要介绍了Java interrupt()方法使用注意_动力节点Java学院整理,需要的朋友可以参考下
    2017-05-05
  • IDEA插件Statistic统计代码快速分辨烂项目

    IDEA插件Statistic统计代码快速分辨烂项目

    这篇文章主要为大家介绍了使用IDEA插件Statistic来统计项目代码,帮助大家快速识别出烂项目,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2022-01-01
  • sqlserver的jdbc配置方法

    sqlserver的jdbc配置方法

    这篇文章主要介绍了sqlserver的jdbc配置方法,需要的朋友可以参考下
    2014-04-04
  • 深入剖析springBoot中的@Scheduled执行原理

    深入剖析springBoot中的@Scheduled执行原理

    这篇文章主要介绍了springBoot中的@Scheduled执行原理,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • java制作android 日历代码分享

    java制作android 日历代码分享

    本文给大家分享的是一段使用java制作Android日历的代码,非常简单实用,实现了读取日历事件、插入事件、编辑日历事件、查看日历等功能,有需要的小伙伴参考下
    2015-03-03

最新评论