SpringBoot整合 Quartz实现定时推送实战指南

本文主要是介绍SpringBoot整合 Quartz实现定时推送实战指南,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《SpringBoot整合Quartz实现定时推送实战指南》文章介绍了SpringBoot中使用Quartz动态定时任务和任务持久化实现多条不确定结束时间并提前N分钟推送的方案,本文结合实例代码给大...

前言

根据需求(多条不确定的结束时间 + 提前 N 分钟推送),Spring Boot 中最优方案是结合 Quartz 动态定时任务 + 任务持久化,支持动态添加 / 删除结束时间、自动计算提前 N 分钟的触发点,且能应对服务重启后任务不丢失的问题。

一、Quartz 是什么?

SpringBoot整合 Quartz实现定时推送实战指南

Quartz 是一个功能强大、开源的任务调度框架,用于实现定时、周期性或基于特定规则的任务执行。简单来说,它就是 Java 生态中 “定时任务” 的标准解决方案,支持复杂的调度逻辑,广泛应用于后台系统的定时任务场景(如定时备份、数据同步、定时推送、报表生成等)。

1、核心定位:解决什么问题?

日常开发中,我们常需要 “在特定时间执行某段代码”,比如:

  • 每天凌晨 2 点执行数据库备份;
  • 每隔 30 分钟同步一次第三方数据;
  • 每月 1 号生成上月报表;
  • 某个固定时间点触发短信推送。

Java 原生提供了 Timer/TimerTask,但存在明显缺陷(如单线程执行、不支持复杂表达式、异常会导致线程终止),无法满足企业级需求。而 Quartz 弥补了这些不足,提供了:

  • 复杂调度规则(支持 Cron 表达式,覆盖几乎所有时间场景);
  • 任务与调度解耦(任务逻辑和执行规则分离);
  • 高可用(支持集群部署,避免单点故障);
  • 可持久化(任务和调度状态可存储到数据库,重启后不丢失);
  • 并发控制(支持任务并发执行或串行执行)。

2、Quartz 核心组件

Quartz 的架构设计清晰,核心组件分为 3 类,需理解它们的职责和关系:

组件作用
Job(任务)具体要执行的 “业务逻辑”,需实现 org.quartz.Job 接口(重写 execute() 方法)。
JobDetail(任务详情)描述 Job 的元数据(如任务名称、分组、是否持久化等),是 Quartz 内部管理 Job 的载体(Job 本身是业务逻辑,JobDetail 是管理配置)。
Trigger(触发器)定义 Job 的 “执行规则”(何时执行、执行频率),是触发 Job 执行的 “开关”。常见实现:SimpleTrigger:简单规则(如延迟 5 秒执行、每隔 10 秒执行 3 次);CronTrigger:复杂规则(基于 Cron 表达式,如每天 02:00 执行)。
Scheduler(调度器)Quartz 的核心 “大脑”,负责管理 JobDetail 和 Trigger,根据 Trigger 规则触发 Job 执行。需通过 SchedulerFactory 创建,是任务调度的入口。

二、使用步骤

1javascript. 引入依赖(Spring Boot + Quartz + 数据库)

需要 Quartz 核心依赖、Spring 整合包,以及数据库依赖(用于任务持久化):

<!-- Spring Boot 整合 Quartz -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<!-- 数据库依赖(以 mysql 为例,用于任务持久化) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

2. 配置文件(application.yml)

配置数据库连接和 Quartz 持久化(关键:禁用内存存储,启用数据库存储):

yaml
spring:
  # 数据库配置(Quartz 任务将存储到该库)
  datasource:
    url: jdbc:mysql://localhost:3306/quartz_db?useSSL=false&serverTimezone=UTC&allowpublicKeyRetrieval=true
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  # JPA 配置(可选,用于存储业务结束时间,方便管理)
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
# Quartz 配置(核心:数据库持久化)
quartz:
  job-store-type: jdbc # 任务存储类型:jdbc(数据库),默认是 memory(内存)
  jdbc:
    initialize-schema: always # 自动创建 Quartz 所需表(首次启动用 always,后续改为 never)
  properties:
    org:
      quartz:
        scheduler:
          instanceName: pushScheduler
          instanceId: AUTO # 集群模式下自动分配实例ID
        jobStore:
          class: org.quartz.impl.jdbcjobstore.JobStoreTX
          driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
          tablePrefix: QRTZ_ # Quartz 表前缀(自动创建的表会带此前缀)
          isClustered: false # 单节点用 false,集群部署改为 true
          clusterCheckinInterval: 20000
        threadPool:
          class: org.quartz.simpl.SimpleThreadPool
          threadCount: 10 # 线程池大小

3. 定义业务实体(存储结束时间,可选但推荐)

用于记录用户添加的 “结束时间”,方便后续查询、修改、删除任务(关联 Quartz 任务 ID):

import jakarta.persistence.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name = "push_task")
public class Pushtask {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id; // 自增ID
    @Column(name = "end_time", nullable = false)
    private LocalDateTime endTime; // 原始结束时间(如明天3点)
    @Column(name = "trigger_time", nullable = false)
    private LocalDateTime triggerTime; // 推送触发时间(endTime -5分钟)
    @Column(name = "quartz_job_id", unique = true, nullable = false)
    private String quartzJobId; // 关联 Quartz 的 JobDetail ID
    @Column(name = "task_desc")
    private String taskDesc; // 任务描述(如“订单123超时提醒”)
    @Column(name = "status")
    private Integer status; // 状态:0-未触发 1-已触发 2-已取消
}

4. 实现消息推送 Job(Quartz 任务逻辑)

Quartz 任务的核心逻辑:触发时执行消息推送,同时更新业务任务状态:

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
 * 消息推送 Job(Quartz 任务)
 */
@Component
public class PushMessageJob implements Job {
    private static final Logger logger = LoggerFactory.getLogger(PushMessageJob.class);
    @Autowired
    private PushTaskRepository pushTaskRepository; // 后续定义的 DAO 接口
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        // 1. 从 Job 上下文获取参数( quartzJobId + 任务描述 )
        String quartzJobId = context.getJobDetail().getKey().getName();
        String taskDesc = (String) context.getJobDetail().getJobDataMap().get("taskDesc");
        String triggerTimeDate = (String) context.getJobDetail().getJobDataMap().get("triggerTime");
        LocalDateTime triggerTime = null;
        if (null != triggerTimeDate) {
            triggerTime = LocalDateTime.parse(triggerTimeDate);
        }
        try {
            // 2. 核心:执行消息推送(替换为你的实际逻辑:短信、APP推送、邮件等)
            doPush(taskDesc, triggerTime);
            // 3. 更新业务任务状态为“已触发”
            pushTaskRepository.updateStatusByQuartzJobId(1, quartzJobId);
            logger.info("消息推送成功!quartzJobId:{},任务描述:{},触发时间:{}",
                    quartzJobId, taskDesc, triggerTime);
        } catch (Exception e) {
            logger.error("消息推送失败!quartzJobId:{}", quartzJobId, e);
            // 可选:抛出异常触发 Quartz 重试(需配置重试策略)
            throw new JobExecutionException("推送失败,触发重试", e, true);
 China编程       }
    }
    /**
     * 实际推送逻辑(根据业务需求替换)
     */
    private void doPush(String taskDesc, LocalDateTime triggerTime) {
        // 示例1:打印日志(实际场景替换为第三方推送接口)
        System.out.printf("[推送通知] 任务描述:%s,触发时间:%s,内容:即将到达结束时间(提前5分钟提醒)%n",
                taskDesc, triggerTime);
        // 示例2:调用 HTTP 推送接口(如极光推送)
        // RestTemplate restTemplate = new RestTemplate();
        // String pushUrl = "https://api.jpush.cn/v3/push";
        // PushRequest request = new PushRequest();
        // request.setContent("即将到达结束时间:" + taskDesc);
        // restTemplate.postForObject(pushUrl, request, String.class);
    }
}

5. 定义 DAO 接口(操作业务任务表)

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
public interface PushTaskRepository extends JpaRepository<PushTask, Long> {
    // 根据 QuartzJobId 查询任务
    PushTask findByQuartzJobId(String quartzJobId);
    // 更新任务状态
    @Modifying
    @Transactional
    @Query("update PushTask t set t.status = :status where t.quartzJobId = :quartzJobId")
    int updateStatusByQuartzJobId(Integer status, String quartzJobId);
    // 根据状态和触发时间查询未执行的任务(服务重启后恢复任务用)
    @Query("select t from PushTask t where t.status = 0 and t.triggerTime > :now")
    List<PushTask> findUnTriggeredTasks(LocalDateTime now);
}

6. 动态定时任务服务(核心:添加 / 删除 / 恢复任务)

封装 Quartz API,实现动态添加任务(自动计算提前 5 分钟)、删除任务、服务重启后恢复未触发任务:

import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
@Service
public class DynamicQuartzService {
    @Autowired
    private Scheduler scheduler;
    @Autowired
    private PushTaskRepository pushTaskRepository;
    // 任务组名(统一分组,方便管理)
    private static final String JOB_GROUP = "PUSH_JOB_GROUP";
    private static final String TRIGGER_GROUP = "PUSH_TRIGGER_GROUP";
    /**
     * 核心方法:添加推送任务(自动计算提前5分钟触发)
     *
     * @params endTime   原始结束时间(如明天3点)
     * @params triggerTime   触发时间(如明天2点)
     * @params taskDesc  任务描述(如“订单123超时提醒”)
     * @return 保存的业务任务
     */
       public PushTask addPushTask(LocalDateTime endTime, LocalDateTime triggerTime,String taskDesc) throws SchedulerException {
        PaAssert.notNull(endTime, "结束时间不能为空!");
        PaAssert.notNull(triggerTime, "触发时间不能为空!");
        // 校验结束时间
        LocalDateTime now = LocalDateTime.now();
        if (endTime.isBefore(now) || endTime.isEqual(now)) {
            throw new IllegalArgumentException("结束时间必须晚于当前时间!");
        }
        if (triggerTime.isBefore(now) || triggerTime.isEqual(now)) {
            throw new IllegalArgumentException("触发时间必须晚于当前时间!");
        }
        // 3. 生成唯一的 QuartzJobId(避免重复)
        String quartzJobId = "PUSH_JOB_" + UUID.randomUUID().toString().replace("-", "");
        // 4. 构建 Quartz JobDetail(绑定 PushMessageJob)
        JobDetail jobDetail = JobBuilder.newJob(PushMessageJob.class)
                .withIdentity(quartzJobId, JOB_GROUP) // 任务ID:quartzJobId,组名:JOB_GROUP
                .usingJobData("taskDesc", taskDesc)
                .usingJobData("triggerTime", String.valueOf(triggerTime))
                .storeDurably() // 持久化(无触发器时也保留)
                .build();
        // 5. 构建 CronTrigger(根据 triggerTime 生成 Cron 表达式)
        String cronExpression = buildCronExpression(triggerTime);
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(quartzJobId, TRIGGER_GROUP)
                .forJob(jobDetail)
                .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)
                        .withMisfireHandlingInstructionFireAndProceed()) // 错过触发时立即执行
                .startNow()
                // 关键:触发时间+1分钟,确保仅执行一次(避免循环或重复触发)
                .endAt(Date.from(triggerTime.plusMinutes(1).atZone(ZoneId.systemDefault()).toInstant()))
                .build();
        // 6. 注册任务到 Quartz 调度器
        scheduler.scheduleJob(jobDetail, trigger);
        // 7. 保存业务任务到数据库(关联 QuartzJobId)
        PushTask pushTask = new PushTask();
        pushTask.setEndTime(endTime);
        pushTask.setTriggerTime(triggerTime);
        pushTask.setQuartzJobId(quartzJobId);
        pushTask.setTaskDesc(taskDesc);
        pushTask.setStatus(0); // 0-未触发
        return pushTaskRepository.save(pushTask);
    }
    /**
     * 删除推送任务(同时删除 Quartz 任务和业务任务)
     * @param quartzJobId 任务ID(添加任务时返回的 quartzJobId)
     */
    public void deletePushTask(String quartzJobId) throws SchedulerException {
        // 1. 停止并删除 Quartz 任务
        JobKey jobKepythony = JobKey.jobKey(quartzJobId, JOB_GROUP);
        TriggerKey triggerKey = TriggerKey.triggerKey(quartzJobId, TRIGGER_GROUP);
        scheduler.pauseTrigger(triggerKey); // 暂停触发器
        scheduler.unscheduleJob(triggerKey); // 移除触发器
        scheduler.deleteJob(jobKey); // 删除任务
        // 2. 更新业务任务状态为“已取消”
        pushTaskRepository.updateStatusByQuartzJobId(2, quartzJobId);
    }
    /**
     * 服务重启后恢复未触发的任务(关键:避免任务丢失)
     */
    public void restoreUnTriggeredTasks() throws SchedulerException {
        // 1. 查询数据库中“未触发”且“触发时间未到”的任务
        List<PushTask> unTriggeredTasks = pushTaskRepository.findUnTriggeredTasks(LocalDateTime.now());
        if (unTriggeredTasks.isEmpty()) {
            return;
        }
        // 2. 重新注册这些任务到 Quartz
        for (PushTask task : unTriggeredTasks) {
            String quartzJobId = task.getQuartzJobId();
            LocalDateTime triggerTime = task.getTriggerTime();
            String taskDesc = task.getTaskDesc();
            // 构建 JobDetail
            JobDetail jobDetail = JobBuilder.newJob(PushMessageJob.class)
                    .withIdentity(quartzJobId, JOB_GROUP)
                    .usingJobData("taskDesc", taskDesc)
                    .usingJobData("triggerTime", String.valueOf(triggerTime))
                    .storeDurably()
                    .build();
            // 构建 Trigger
            String cronExpression = buildCronExpression(triggerTime);
            CronTrigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(quartzJobId, TRIGGER_GROUP)
                    .forJob(jobDetail)
                    .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
                    .startNow()
                    .build();
            // 注册任务
            scheduler.scheduleJob(jobDetail, trigger);
        }
        System.out.printf("恢复未触发的推送任务数量:%d%n", unTriggeredTasks.size());
    }
    /**
     * 工具方法:将 LocalDateTime 转换为 Cron 表达式(精准到秒)
     * Cron 格式:秒 分 时 日 月 周 年(年可选)
     * 例:2025-11-01 02:55:00 → 0 55 2 1 11 ? 2025
     */
    private Stringpython buildCronExpression(LocalDateTime triggerTime) {
        int second = triggerTime.getSecond(); // 秒(0)
        int minute = triggerTime.getMinute(); // 分(0)
        int hour = triggerTime.getHour();     // 时(16)
        int day = triggerTime.getDayOfMonth();// 日(21)
        int month = triggerTime.getMonthValue();// 月(11,LocalDateTime 直接是 1-12,无需+1)
        int year = triggerTime.getYear();     // 年(2025)
        // Cron 格式:秒 分 时 日 月 ? 年 → 周字段用 ?,避免与日冲突
        return String.format("%d %d %d %d %d ? %d",
                second, minute, hour, day, month, year);
    }
}

7. 启动时恢复任务(监听服务启动)

服务重启后,自动恢复数据库中 “未触发” 的任务,避免任务丢失:

import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class TaskRestoreRunner implements ApplicationRunner {
    @Autowired
    private DynamicQuartzService dynamicQuartzService;
    @Override
    public void run(ApplicationArguments args) throws SchedulerException {
        // 服务启动后,恢复未触发的任务
        dynamicQuartzService.restoreUnTriggeredTasks();
    }
}

8. 测试接口(对外提供添加 / 删除任务的入口)

通过 HTTP 接口测试动态添加、删除任务:

import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
@RestController
@RequestMapping("/push")
public class PushTaskController {
    @Autowired
    private DynamicQuartzService dynamicQuartzService;
    /**
     * 添加推送任务
     * @param endTime 结束时间(格式:yyyy-MM-dd HH:mm:ss,如 2025-11-01 03:00:00)
     * @param taskDesc 任务描述
     */
    @PostMapping("/add")
    public PushTask addTask(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @RequestParam String taskDesc) throws SchedulerException {
        return dynamicQuartzService.addPushTask(endTime, taskDesc);
    }
    /**
     * 删除推送任务
     * @param quartzJobId 任务Iwww.chinasem.cnD(添加任务时返回的 quartzJobId)
     */
    @PostMapping("/delete")
    public String deleteTask(@RequestParam String quartzJobId) throws SchedulerException {
        dynamicQuartzService.deletePushTask(quartzJobId);
        return "任务删除成功!quartzJobId:" + quartzJobId;
    }
}

三、核心功能测试

1. 添加任务测试

发送 POST 请求:

plaintext http://localhost:8080/push/add?endTime=2025-11-01
03:00:00&taskDesc=订单123超时提醒

  • 后台会自动计算触发时间:2025-11-01 02:55:00;
  • 数据库 push_task 表会新增一条记录,状态为 0(未触发);
  • Quartz 会创建对应的 Job 和 Trigger,到 02:55 自动触发推送。

2. 触发效果

到触发时间后,控制台会输出:

[推送通知] 任务描述:订单123超时提醒,触发时间:2025-11-01T02:55,内容:即将到达结束时间(提前5分钟提醒)

同时 push_task 表中该任务的状态会更新为 1(已触发)。

3. 删除任务测试

发送 POST 请求:

http://localhost:8080/push/delete?quartzJobId=PUSH_JOB_xxx(添加任务时返回的
quartzJobId)

  • Quartz 会删除对应的 Job 和 Trigger;
  • 数据库中任务状态更新为 2(已取消)。

四、关键特性说明

1. 动态性

  • 支持任意多条结束时间:调用 addPushTask 方法可添加多个任务,每个任务独立触发;
  • 结束时间不确定:无需提前配置 Cron 表达式,传入 LocalDateTime 即可自动生成触发规则。

2. 可靠性

  • 持久化:任务信息存储在数据库,服务重启后自动恢复未触发的任务;
  • 失败重试:推送失败时抛出异常,Quartz 会根据配置的策略重试(默认重试 3 次);
  • 集群支持:修改 application.yml 中 quartz.properties.org.quartz.jobStore.isClustered=true,即可支持集群部署(避免重复触发)。

3. 灵活性

  • 提前时间可配置:将 minusMinutes(5) 改为参数(如 minusMinutes(提前分钟数)),支- - 持动态调整提前提醒时间;
  • 推送逻辑可扩展:修改 doPush 方法,整合短信、APP 推送(极光 / 个推)、邮件等任意渠道。

4. 时间校验

  • 避免添加已过期的任务(结束时间早于当前时间);
  • 避免提前 5 分钟后仍过期的任务(如结束时间为当前时间 + 3 分钟,提前 5 分钟则已过期)。

五、生产环境优化建议

1.任务监控:通过 Quartz 提供的 API 监控任务状态(如查询所有任务、触发次数、失败次数),或集成 Prometheus + Grafana 可视化监控;

2.过期任务清理:定时清理数据库中 “已触发” 或 “已取消” 的任务(避免表数据过大);

3.推送异步化:如果推送逻辑耗时较长(如调用第三方接口),可在 doPush 中发送 MQ 消息,由消费者异步处理推送(解耦定时任务和推送逻辑);

4.日志增强:记录推送结果(成功 / 失败)到日志文件或数据库,方便问题排查;

5.权限控制:对 /push/add 和 /push/delete 接口添加权限校验(如 Token 验证),避免恶意操作。

总结

本方案通过 Quartz 动态任务 + 数据库持久化,完美满足 “多条不确定结束时间 + 提前 5 分钟推送” 的需求,核心优势:

  • 动态灵活:支持任意结束时间,无需提前配置;
  • 可靠稳定:任务持久化、服务重启恢复、失败重试;
  • 易于扩展:支持多推送渠道、集群部署、监控告警。

如果需要轻量级方案(无需持久化,服务重启后任务可丢失),也可使用 Spring Scheduler + 内存缓存,但生产环境建议优先选择本方案(可靠性更高)

到此这篇关于SpringBoot整合 Quartz实现定时推送实战指南的文章就介绍到这了,更多相关SpringBoot Quartz定时推送内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于SpringBoot整合 Quartz实现定时推送实战指南的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1156409

相关文章

Nginx更新SSL证书的实现步骤

《Nginx更新SSL证书的实现步骤》本文主要介绍了Nginx更新SSL证书的实现步骤,包括下载新证书、备份旧证书、配置新证书、验证配置及遇到问题时的解决方法,感兴趣的了解一下... 目录1 下载最新的SSL证书文件2 备份旧的SSL证书文件3 配置新证书4 验证配置5 遇到的http://www.cppc

Nginx之https证书配置实现

《Nginx之https证书配置实现》本文主要介绍了Nginx之https证书配置的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起... 目录背景介绍为什么不能部署在 IIS 或 NAT 设备上?具体实现证书获取nginx配置扩展结果验证

Java利用Spire.XLS for Java自动化设置Excel的文档属性

《Java利用Spire.XLSforJava自动化设置Excel的文档属性》一个专业的Excel文件,其文档属性往往能大大提升文件的可管理性和可检索性,下面我们就来看看Java如何使用Spire... 目录Spire.XLS for Java 库介绍与安装Java 设置内置的 Excel 文档属性Java

Java中的CompletableFuture核心用法和常见场景

《Java中的CompletableFuture核心用法和常见场景》CompletableFuture是Java8引入的强大的异步编程工具,支持链式异步编程、组合、异常处理和回调,介绍其核心用法,通过... 目录1、引言2. 基本概念3. 创建 CompletableFuture3.1. 手动创建3.2.

java中4种API参数传递方式统一说明

《java中4种API参数传递方式统一说明》在Java中,我们可以使用不同的方式来传递参数给方法或函数,:本文主要介绍java中4种API参数传递方式的相关资料,文中通过代码介绍的非常详细,需要的... 目录1. 概述2. 参数传递方式分类2.1 Query Parameters(查询参数)2.2 Path

Java线程池核心参数原理及使用指南

《Java线程池核心参数原理及使用指南》本文详细介绍了Java线程池的基本概念、核心类、核心参数、工作原理、常见类型以及最佳实践,通过理解每个参数的含义和工作原理,可以更好地配置线程池,提高系统性能,... 目录一、线程池概述1.1 什么是线程池1.2 线程池的优势二、线程池核心类三、ThreadPoolE

使用Redis实现会话管理的示例代码

《使用Redis实现会话管理的示例代码》文章介绍了如何使用Redis实现会话管理,包括会话的创建、读取、更新和删除操作,通过设置会话超时时间并重置,可以确保会话在用户持续活动期间不会过期,此外,展示了... 目录1. 会话管理的基本概念2. 使用Redis实现会话管理2.1 引入依赖2.2 会话管理基本操作

Springboot请求和响应相关注解及使用场景分析

《Springboot请求和响应相关注解及使用场景分析》本文介绍了SpringBoot中用于处理HTTP请求和构建HTTP响应的常用注解,包括@RequestMapping、@RequestParam... 目录1. 请求处理注解@RequestMapping@GetMapping, @PostMappin

Java调用DeepSeek API的8个高频坑与解决方法

《Java调用DeepSeekAPI的8个高频坑与解决方法》现在大模型开发特别火,DeepSeek因为中文理解好、反应快、还便宜,不少Java开发者都用它,本文整理了最常踩的8个坑,希望对... 目录引言一、坑 1:Token 过期未处理,鉴权异常引发服务中断问题本质典型错误代码解决方案:实现 Token

mybatis-plus分表实现案例(附示例代码)

《mybatis-plus分表实现案例(附示例代码)》MyBatis-Plus是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生,:本文主要介绍my... 目录文档说明数据库水平分表思路1. 为什么要水平分表2. 核心设计要点3.基于数据库水平分表注意事项示例