SpringBoot整合Quartz以及异步调用

news2025/1/31 11:00:50

文章目录

  • 前言
  • 一、异步方法调用
    • 1、导入依赖
    • 2、创建异步执行任务线程池
    • 3、创建业务层接口和实现类
    • 4、创建业务层接口和实现类
  • 二、测试定时任务
    • 1.导入依赖
    • 2.编写测试类,开启扫描定时任务
    • 3.测试
  • 三、实现定时发送邮件案例
    • 1.邮箱开启IMAP服务
    • 2.导入依赖
    • 3.导入EmailUtil
    • 4.编写邮件发送方法
    • 5.开启异步和定时任务
  • 总结


前言

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);
    }

}

测试:
此处不再演示


总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/396531.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为「IT女神勋章」而战

大家好&#xff0c;我是空空star&#xff0c;今天为「IT女神勋章」而战 文章目录前言一、IT女神勋章二、绘制爱心1.htmlcssjs来源&#xff1a;一行代码代码效果2.python来源&#xff1a;C知道代码效果3.go来源&#xff1a;复制代码片代码效果4.java来源&#xff1a;download代码…

游戏算法-游戏AI状态机,python实现

AI概述 游戏AI是对游戏内所有非玩家控制角色的行为进行研究和设计&#xff0c;使得游戏内的单位能够感知周围环境&#xff0c;并做出相应的动作表现的技术。游戏AI作为游戏玩法的一大补充&#xff0c;在各种游戏中都有广泛的应用&#xff0c;比如可以和玩家交互聊天的NPC&#…

用户体验设计—影响定制化设计的因素

0 前言最近在上信息构建这门课&#xff08;名为信息构建&#xff0c;但感觉叫用户体验设计更好。。。&#xff09;老师是研究信息行为、人智交互这块的&#xff0c;所以实验课要求我们先学习一个实际的设计案例&#xff0c;让我们搞懂影响定制化设计的因素。所以这篇文章讲讲我…

七色电子标签

机种名 电子会议桌牌 型号 ESL_7color_7.3_D 外观尺寸 176.2x137.15x80mm 产品重量 268g 可视区域 163.297.92mm 外观颜色 银色 供电方式 锂电池供电2300mAh&#xff08;Type-C 接口可充电&#xff09; 显示技术 E-INK电子纸&#xff0c;双屏 像素 800x480 像…

ByteTrack: Multi-Object Tracking by Associating Every Detection Box 论文详细解读

ByteTrack: Multi-Object Tracking by Associating Every Detection Box 论文详细解读 文章目录ByteTrack: Multi-Object Tracking by Associating Every Detection Box 论文详细解读ByteTrackByteTrack算法简介ByteTrack算法流程ByteTrack算法描述一&#xff1a;对检测框进行分…

SOA架构的理解

1. SOA概述 SOA&#xff08;Service-Oriented Architecture&#xff0c;面向服务的架构&#xff09;是一种在计算机环境中设计、开发、部署和管理离散模型的方法。SOA不是一种新鲜事物&#xff0c;它是在企业内部IT系统重复构建以及效率低下的背景下提出的。在SOA模型中&#x…

Nexus 3 清理docker镜像

该文章提供了一种清理nexus3中存储的docker镜像的一种新思路 查看docker repo 比如你的docker repo名字叫做test-repo&#xff0c;然后在nexus3首页的seatch下面找到docker&#xff0c;点进去随便查看一个已经上传的镜像 记住上面的Name选项&#xff0c;之后要用到 设定清理…

centos7 oracle19c安装||新建用户|| ORA-01012: not logged on

总共分三步 1.下载安装包:里面有一份详细的安装教程 链接&#xff1a;https://pan.baidu.com/s/1Of2a72pNLZ-DDIWKrTQfLw?pwd8NAx 提取码&#xff1a;8NAx 2.安装后,执行初始化:时间较长 /etc/init.d/oracledb_ORCLCDB-19c configure 3.配置环境变量,不配置环境变量,sq…

【Linux快速入门】文件目录操作

文章目录概念1. Linux文件系统概述2. Linux文件目录结构3. Linux文件和目录操作3.1 文件操作3.1.1 创建文件3.1.2 复制文件3.1.3 移动文件3.1.4 删除文件3.1.5 查看文件3.1.6 输出指令3.1.7 >和>>指令3.2 目录操作3.2.1 创建目录3.2.2 复制目录3.2.3 移动目录3.2.4 删…

Lesson 8.3 ID3、C4.5 决策树的建模流程 Lesson 8.4 CART 回归树的建模流程与 sklearn 参数详解

文章目录一、ID3 决策树的基本建模流程二、C4.5 决策树的基本建模流程1. 信息值&#xff08;information value&#xff09;2. C4.5 的连续变量处理方法三、CART 回归树的基本建模流程1. 数据准备2. 生成备选规则3. 挑选规则4. 进行多轮迭代5. 回归树的预测过程四、CART 回归树…

关于推荐系统的详细介绍

简介推荐系统是一种信息过滤系统&#xff0c;能够自动预测用户对特定产品或服务的偏好&#xff0c;并向其提供个性化的推荐。它通常基于用户的历史行为、个人喜好、兴趣和偏好等&#xff0c;通过数据挖掘和机器学习算法&#xff0c;在大数据的支持下生成个性化的推荐内容&#…

智云通CRM:与权力者沟通的策略有哪些?

权力者通常具备两个特点&#xff1a;忙和目标导向 1.忙 权力者都很忙&#xff08;不忙也会装出很忙的样子&#xff09;&#xff0c;时间精力有限&#xff0c;销售人员眼里的大项目在权力者看来很有可能只是他诸多工作中的一项。因此&#xff0c;即使有不满者的引荐&#xff0c;…

ChatGPT露馅了,它明明就是人

让人工智能理解句子成分和语义&#xff0c;这看起来是件不可能的事&#xff0c;看过流浪地球的都知道&#xff0c;那里面的人工智能哪怕发展到2057年&#xff0c;也听不懂比喻和反问。 那最近大火的chatGPT能不能听懂冷笑话呢&#xff1f;它不仅能写代码、论文&#xff0c;居然…

Spring学习——拦截器

拦截器概念 拦截器&#xff08;Interceptor )是一种动态拦截方法调用的机制&#xff0c;在SpringMVC中动态拦截控制器方法的执行作用: 在指定的方法调用前后执行预先设定的代码阻止原始方法的执行 拦截器与过滤器区别 归属不同&#xff1a;Filter属于Servlet技术&#xff0…

[oeasy]python0101_尾声_PC_wintel_8080_诸神的黄昏_arm_riscv

尾声 回忆上次内容 回顾了 ibm 使用开放架构 用 pc兼容机 战胜了 dec 小型机apple 个人电脑 触击牺牲打 也破掉了 自己 软硬一体全自主的 金身 借助了 各种 软硬件厂商的 力量 最终完成了 pc架构上 的 大一统 操作系统层面 IBM 计划让 msdos和cp/m 分庭抗礼为什么 最后微软…

NC xml配置文件不能生产java文件

在NC开发过程中&#xff0c;新增、或修改了xml文件&#xff0c;在开发工具eclipse中生成或重新生成Java文件&#xff0c;发现生成不了相对应的Java文件。如下图&#xff0c;选中xml文件后&#xff0c;右键点击SpringXml to Java 这种情况其实一般都是xml配置文件有问题&#…

敏捷项目管理的概念,以及与传统项目管理的区别

较之瀑布等传统项目管理模式&#xff0c;敏捷是“适应性的”&#xff0c;而非“预设性的”。团队采用敏捷项目管理可以提高交付速度、协作效率、以及响应市场变化的能力。在这里向大家详细介绍敏捷项目管理的定义、与传统项目管理的区别&#xff0c;以及一些主流的敏捷项目框架…

下一代ERP系统是什么样的呢?什么是智能化ERP系统?AI能改变ERP系统吗?

下一代ERP系统是什么样的呢&#xff1f;什么是智能化ERP系统&#xff1f;AI能改变ERP系统吗&#xff1f;导读1. 用户体验&#xff1a;2. 作业、分析和智能一体化2.1 ERP之采购管理&#xff1a;2.2 ERP之零售商品管理&#xff1a;2.3 ERP之会计和财务管理3. 系统处理大数据导读 …

嵌入式Linux从入门到精通之第十六节:U-boot分析

简介 u-boot最初是由PPCBoot发展而来的,可以引导多种操作系统、支持多种架构的CPU,它对PowerPC系列处理器的支持最为完善,而操作系统则对Linux系统的支持最好目前已成为Armboot和PPCboot的替代品。 特点: 主要支持操作系统:Linux、NetBSD、 VxWorks、QNX、RTEMS、ARTOS、L…

Vue3分页器(Pagination)

自定义传入&#xff1a; 当前页数&#xff08;current&#xff09;&#xff0c;默认为1每页条数&#xff08;pageSize&#xff09;&#xff0c;默认为10只有一页时是否隐藏分页器&#xff08;hideOnSinglePage&#xff09;&#xff0c;默认为false数据总数&#xff08;total&a…