进阶SpringBoot之异步任务、邮件任务和定时执行任务

news2024/11/15 17:50:35

SpringBooot 创建 Web 项目

异步任务:

service 包下创建 AsyncService 类

@Async 异步方法

Thread.sleep(3000)  停止三秒,捕获异常

package com.demo.task.service;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

//异步
@Service
public class AsyncService {

    //异步方法
    @Async
    public void hello(){
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            //throw new RuntimeException(e);
            e.printStackTrace();
        }
        System.out.println("数据正在处理");
    }
}

controller 包下创建 AsyncController 类

自动装配 AsyncService

方法里调用 AsyncService 类里的 hello 方法,停止三秒

package com.demo.task.controller;

import com.demo.task.service.AsyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AsyncController {

    @Autowired
    AsyncService asyncService;

    @RequestMapping("/hello")
    public String hello(){
        asyncService.hello();
        return "OK";
    }
}

主程序添加 @EnableAsync 开启异步注解功能

package com.demo.task;

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

@EnableAsync //开启异步注解功能
@SpringBootApplication
public class TaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(TaskApplication.class, args);
    }
}

启动即可,记得地址加后缀

(加了注解后,实际上响应很快,页面很快出现,但程序执行过了三秒,就是输出的那句“数据正在处理”过了三秒出现)

邮件任务:

pom.xml 导入 spring-boot-starter-mail 的 jar 包

        <!-- 导入javax.mail -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

拿 qq 邮箱举例,点击设置 -> 账号,下滑找到 POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV 服务

点击管理服务,获取到授权码

application.properties 配置邮箱信息:

#邮箱账号
spring.mail.username=xx@qq.com
#邮箱密码:授权码
spring.mail.password=xx
spring.mail.host=smtp.qq.com
#开启加密验证
spring.mail.properties.mail.smtp.ssl.enable=true

测试类:

自动装配 JavaMailSenderImpl

new 一个 SimpleMailMessage,调用邮件相关信息

最后发送即可

package com.demo.task;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;

@SpringBootTest
class TaskApplicationTests {

    @Autowired
    JavaMailSenderImpl mailSender;

    @Test
    void contextLoads() {

        SimpleMailMessage message = new SimpleMailMessage();

        message.setSubject("邮件主题");
        message.setText("文本内容");

        message.setTo("xx@qq.com");
        message.setFrom("xx@qq.com");

        mailSender.send(message);
    }

}

上述只是简单的邮件,复杂邮件如下:

createMimeMessage -> new MimeMessageHelper -> ... -> send

package com.demo.task;

import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;

import java.io.File;

@SpringBootTest
class TaskApplicationTests {

    @Autowired
    JavaMailSenderImpl mailSender;

    @Test
    void contextLoads2() throws MessagingException {

        MimeMessage mimeMessage = mailSender.createMimeMessage();

        //组装
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true,"utf-8");

        helper.setSubject("邮件主题");
        helper.setText("<p style='color:red'>文本内容</p>",true);

        //附件
        helper.addAttachment("1.jpg",new File("E:\\1.jpg"));

        helper.setTo("xx@qq.com");
        helper.setFrom("xx@qq.com");

        mailSender.send(mimeMessage);
    }

}

定时任务:

主程序类上添加一行 @EnableScheduling 开启定时功能

package com.demo.task;

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

@EnableAsync //开启异步注解功能
@EnableScheduling //开启定时功能的注解
@SpringBootApplication
public class TaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(TaskApplication.class, args);
    }
}

service 包下创建 ScheduledService 类:

方法上添加 @Scheduled 注解

package com.demo.task.service;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Service
public class ScheduledService {

    //定时:在一个特定的时间执行程序
    //core表达式:      秒 分 时 日 月 周几
    //                0/2 14 13 ? * 1-5   每个月周一到周五13点14分,每隔两秒执行一次
    @Scheduled(cron = "0 20 5 * * ?")  //每天5点20分0秒执行方法
    public void hello(){
        System.out.println("hello");
    }
}

查看 Scheduled 源码,提供了多种配置调度任务的方式

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
@Reflective
public @interface Scheduled {
    String CRON_DISABLED = "-";

    String cron() default "";

    String zone() default "";

    long fixedDelay() default -1L;

    String fixedDelayString() default "";

    long fixedRate() default -1L;

    String fixedRateString() default "";

    long initialDelay() default -1L;

    String initialDelayString() default "";

    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;

    String scheduler() default "";
}

Cron 在线表达式生成器

可以实现在线生成表达式

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

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

相关文章

【MySQL】Windows下重启MySQL服务时,报错:服务名无效

1、问题描述 在终端中&#xff0c;停止、启动MySQL服务时报错&#xff1a;服务名无效 2、原因分析 1&#xff09;权限不够 如果是权限不够&#xff0c;会提示&#xff1a;系统错误5&#xff0c;拒绝访问。 2&#xff09;服务名错误 如果是服务名错误&#xff0c;会提示“…

第313题|解积分不等式题目的5种方法常用方法|武忠祥老师每日一题

解题思路&#xff1a;把多阶次积分和函数值联系起来&#xff0c;应该想到泰勒公式。 本题应该使用带有拉格朗日余项的泰勒公式&#xff1a; 方法一&#xff1a; 等式左右两边进行积分&#xff0c;右边第一项常数项不变&#xff0c;第二项&#xff08;x-1/2&#xff09;积完之…

macOS Sequoia 正式版(24A335)黑苹果/Mac/虚拟机系统镜像

“ 以下内容来自于黑果魏叔官网” 镜像特点 完全由黑果魏叔官方制作&#xff0c;针对各种机型进行默认配置&#xff0c;让黑苹果安装不再困难。系统镜像设置为双引导分区&#xff0c;全面去除clover引导分区&#xff08;如有需要&#xff0c;可以自行直接替换opencore分区文件为…

web安全测试入门

参考课程&#xff1a; 04-软件安全测试基础-网络协议基础-网络模型_哔哩哔哩_bilibili 1.软件安全测试概述 安全测试&#xff1a; 安全性测试指有关验证应用程序的安全等级和识别潜在安全性缺陷的过程 导致软件出现安全问题的主要原因或根源是软件的安全漏洞 安全漏洞&#x…

网页交互模拟:模拟用户输入、点击、选择、滚动等交互操作

目录 一、理论基础 1.1 网页交互模拟的重要性 1.2 网页交互的基本原理 二、常用工具介绍 2.1 Selenium 2.2 Puppeteer 2.3 Cypress 2.4 TestCafe 三、实战案例 3.1 模拟用户输入 3.2 模拟用户点击 3.3 模拟用户选择 3.4 模拟滚动操作 四、最佳实践与优化 4.1 代…

基于python+django+vue的学生管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于协同过滤pythondjangovue…

Python编码系列—Python原型模式:深克隆与高效复制的艺术

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

C++的IO流(文件部分在这里)

1. C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键盘)读取数据&#xff0c;并将值存放在变量中。printf(): 将指定的文字/字符串输出到标准输出设备(屏幕)。 注意宽度输出和精度输出控制。C语言借助了相应的缓…

嵌入式开发—CAN通信协议详解与应用(上)

文章目录 1.CAN简介CAN协议的诞生背景CAN协议的发展历程CAN协议的影响CAN通信的主要特点 2.CAN数据帧的帧格式CAN标准数据帧的帧格式CAN标准数据帧的帧格式结构图CAN扩展帧的帧格式CAN遥控帧的帧格式CAN错误帧的帧格式 3.CAN数据传输中的位填充位填充的概念位填充的作用位填充的…

今天中秋,中秋快乐,分析一个中秋月饼的项目

特色功能 使用obj模型&#xff0c;搭配tga文件&#xff0c;附加上颜色 normalMap 是让字和线条看起来更清楚和真实 高光贴图 凹凸贴图 ...... 源码 https://github.com/Lonely1201/lonely1201.github.io/tree/main/Juejin/mooncake 在线预览 https://lonely1201.githu…

将YYYY-MM-DD HH:mm:ss格式化为YYYY-MM-DD (星期一) 下午 ?点

分为凌晨、早上、中午、晚上 function formatDate(inputDate) {const date new Date(inputDate);date.setHours(date.getHours() - 1);const year date.getFullYear();const month date.getMonth() 1; // 月份从0开始const day date.getDate();let hours date.getHours(…

详解:Tensorflow、Pytorch、Keras

这是一个专门对Tensorflow、Pytorch、Keras三个主流DL框架的一个详解和对比分析 一、何为深度学习框架&#xff1f; 你可以理解为一个工具帮你构建一个深度学习网络&#xff0c;调用里面的各种方法就能自行构建任意层&#xff0c;diy你想要的DNN&#xff0c;而且任意指定学习…

用Qt 对接‌百度语音识别接口

一 、前期准备工作 1&#xff0c;搭建好开发环境&#xff1b; 2&#xff0c;注册百度云平台&#xff0c;获取语音相关东西&#xff0c; 短语音识别标准版_短语音识别-百度AI开放平台 (baidu.com) 3&#xff0c;涉及到的Qt 类有 QAudioFormat&#xff0c;QAudioDeviceInfo&a…

JDBC实现对单表数据增、删、改、查

文章目录 API介绍获取 Statement 对象Statement的API介绍使用步骤案例代码 JDBC实现对单表数据查询ResultSet的原理ResultSet获取数据的API使用JDBC查询数据库中的数据的步骤案例代码 API介绍 获取 Statement 对象 在java.sql.Connection接口中有如下方法获取到Statement对象…

线程池是啥有啥用,怎么用,如何自己实现一个

目录 一、线程池是啥&#xff0c;有啥用 二、线程池怎么用 1.构造方法 2.如何使用Java的线程池 三、简单实现一个线程池 假设我是一个&#xff08;好看有才华&#xff09; 的妹子&#xff0c;那么我就会有很多追求者&#xff0c;这些也叫备胎们&#xff0c;我们若把他…

71、哪吒开发板试用结合oak深度相机进行评测

基本思想:收到intel的开发板-小挪吒,正好手中也有oak相机,反正都是openvino一套玩意,进行评测一下,竟然默认是个window系统,哈哈

STL-vector练习题

118. 杨辉三角 思路&#xff1a; 杨辉三角有以下性质使我们要用到的&#xff1a; ● 每行数字左右对称&#xff0c;由 1 开始逐渐变大再变小&#xff0c;并最终回到 1。 ● 第 n 行&#xff08;从 0 开始编号&#xff09;的数字有 n1 项&#xff0c;前 n 行共有 2n(n1)个数。…

linux重要文件

/etc/sysconfig/network-scripts/ifcfg-eth1 网卡重启 /etc/init.d/network restart ifup ethname & ifdown ethname /etc/resolv.conf 设置Linux本地的客户端DNS的配置文件 linux客户端DNS可以在网卡配置文件(/etc/sysconfig/network/ifcfg-eth0 DNS2)里配置 也可以在/et…

SSY20240916提高组T1题解__贪心+大模拟

题面 题面描述 fe和xt在玩一个游戏, 在 n m n\times m nm的网格图上进行. 定义 ( a , b ) , ( c , d ) (a,b)\;,\;(c,d) (a,b),(c,d)见距离为 ∣ a − c ∣ ∣ b − d ∣ |a-c||b-d| ∣a−c∣∣b−d∣ 现在游戏按照以下步骤进行: xt选择 k k k个格子fe选择一个格子(不能选…

QT + WebAssembly + Vue环境搭建

Qt6.7.2安装工具 emsdk安装 git clone https://github.com/emscripten-core/emsdk.git cd emsdk emsdk install 3.1.50 emsdk activate 3.1.50 Qt Creator配置emsdk 效果 参考 GitHub - BrockReece/vue-wasm: Vue web assembly loader Emscripten cmake多版本编译-CSDN博客 …