代码:
package com.weiyu.config;
import com.weiyu.service.CompositeConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* 定时任务配置类
*/
@Configuration
@EnableScheduling
@Slf4j
public class ScheduleConfig implements SchedulingConfigurer {
@Autowired
private CompositeConfigService compositeConfigService;
/**
* 配置定时任务线程池
*/
@Bean(destroyMethod = "shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(5, r -> {
Thread t = new Thread(r);
t.setDaemon(true);
t.setName("schedule-task-" + t.getId());
return t;
});
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
Long interval = compositeConfigService.getCheckIntervalMs();
log.info("定时任务配置完成,超时检查间隔: {}ms", interval);
}
/**
* 获取超时检查间隔(用于@Scheduled注解)
* 该方法通过SpEL在@Scheduled注解中调用,IDEA会误报未使用警告
*/
@SuppressWarnings("unused")
public Long getTimeoutCheckInterval() {
return compositeConfigService.getCheckIntervalMs();
}
/**
* 获取请求超时时间(秒)
*/
public Integer getRequestTimeoutSeconds() {
return compositeConfigService.getRequestTimeoutSeconds();
}
/**
* 是否启用超时检查
*/
public Boolean isTimeoutCheckEnabled() {
return compositeConfigService.isTimeoutCheckEnabled();
}
}
我来详细讲解这个Spring Boot定时任务配置类的每一部分,特别适合新手理解。
类定义和注解
java
@Configuration @EnableScheduling @Slf4j public class ScheduleConfig implements SchedulingConfigurer
-
@Configuration: 标识这是一个配置类,Spring Boot启动时会自动加载 -
@EnableScheduling: 开启Spring的定时任务功能 -
@Slf4j: Lombok注解,自动生成日志对象log -
SchedulingConfigurer: 接口,允许自定义定时任务的配置
依赖注入
java
@Autowired private CompositeConfigService compositeConfigService;
注入配置服务,用于动态获取定时任务的参数(如间隔时间、是否启用等)。
核心配置方法
1. 线程池配置
java
@Bean(destroyMethod = "shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(5, r -> {
Thread t = new Thread(r);
t.setDaemon(true);
t.setName("schedule-task-" + t.getId());
return t;
});
}
详细解释:
-
@Bean(destroyMethod = "shutdown"): 创建Bean,容器关闭时自动调用shutdown方法 -
Executors.newScheduledThreadPool(5, ...): 创建包含5个线程的调度线程池 -
线程工厂:
-
setDaemon(true): 设置为守护线程,JVM关闭时自动结束 -
setName(...): 给线程命名,便于监控和调试
-
2. 定时任务配置
java
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
Long interval = compositeConfigService.getCheckIntervalMs();
log.info("定时任务配置完成,超时检查间隔: {}ms", interval);
}
作用: 将自定义线程池设置给Spring的定时任务系统。
配置获取方法
java
public Long getTimeoutCheckInterval() {
return compositeConfigService.getCheckIntervalMs();
}
public Integer getRequestTimeoutSeconds() {
return compositeConfigService.getRequestTimeoutSeconds();
}
public Boolean isTimeoutCheckEnabled() {
return compositeConfigService.isTimeoutCheckEnabled();
}
这些方法的使用场景:
在具体的定时任务类中,通过SpEL表达式调用:
java
@Component
public class MyScheduledTask {
@Scheduled(fixedRateString = "#{@scheduleConfig.getTimeoutCheckInterval()}")
public void checkTimeout() {
// 定时任务逻辑
}
@Scheduled(fixedRate = 5000)
public void anotherTask() {
// 可以直接使用配置值
}
}
新手需要理解的重点
1. 为什么需要自定义线程池?
-
默认情况下,Spring使用单线程执行所有定时任务
-
如果某个任务执行时间过长,会阻塞其他任务
-
自定义线程池可以并行执行多个定时任务
2. 动态配置的优势
java
// 动态获取配置,可以在运行时修改 Long interval = compositeConfigService.getCheckIntervalMs(); // 对比硬编码方式(不推荐) // @Scheduled(fixedRate = 5000)
3. 完整的项目结构示例
text
src/main/java/
├── config/
│ └── ScheduleConfig.java # 你现在看的这个文件
├── service/
│ ├── CompositeConfigService.java # 配置服务
│ └── SomeBusinessService.java # 业务服务
└── task/
└── TimeoutCheckTask.java # 具体的定时任务类
4. 定时任务类示例
java
@Component
@Slf4j
public class TimeoutCheckTask {
@Autowired
private ScheduleConfig scheduleConfig;
// 使用动态间隔时间
@Scheduled(fixedRateString = "#{@scheduleConfig.getTimeoutCheckInterval()}")
public void checkRequestTimeout() {
if (!scheduleConfig.isTimeoutCheckEnabled()) {
return; // 根据配置决定是否执行
}
log.info("执行超时检查,超时时间: {}秒",
scheduleConfig.getRequestTimeoutSeconds());
// 具体的业务逻辑...
}
}
总结
这个配置类主要实现了:
-
✅ 自定义定时任务线程池
-
✅ 动态配置定时任务参数
-
✅ 统一的配置管理
-
✅ 良好的线程管理和资源清理
对于新手来说,理解这个配置类是掌握Spring Boot定时任务高级用法的重要一步!
我来详细讲解这个Spring Boot定时任务配置类:
类级别注解
java
@Configuration // 声明为配置类 @EnableScheduling // 启用Spring定时任务功能 @Slf4j // Lombok日志注解 public class ScheduleConfig implements SchedulingConfigurer
核心组件解析
1. 线程池配置
java
@Bean(destroyMethod = "shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(5, r -> {
Thread t = new Thread(r);
t.setDaemon(true); // 设置为守护线程
t.setName("schedule-task-" + t.getId()); // 线程命名,便于监控
return t;
});
}
-
线程池大小:5个核心线程
-
守护线程:应用关闭时自动终止,不会阻止JVM退出
-
线程命名:便于在日志和监控工具中识别
2. 定时任务配置
java
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor()); // 设置自定义线程池
Long interval = compositeConfigService.getCheckIntervalMs();
log.info("定时任务配置完成,超时检查间隔: {}ms", interval);
}
-
替换Spring默认的单线程调度器,避免任务相互阻塞
-
支持多个定时任务并行执行
3. 动态配置方法
java
public Long getTimeoutCheckInterval() {
return compositeConfigService.getCheckIntervalMs();
}
public Integer getRequestTimeoutSeconds() {
return compositeConfigService.getRequestTimeoutSeconds();
}
public Boolean isTimeoutCheckEnabled() {
return compositeConfigService.isTimeoutCheckEnabled();
}
使用示例
在其他组件中使用这些配置:
java
@Service
public class TimeoutCheckService {
@Scheduled(fixedRateString = "#{@scheduleConfig.getTimeoutCheckInterval()}")
public void checkTimeout() {
if (scheduleConfig.isTimeoutCheckEnabled()) {
// 执行超时检查逻辑
Integer timeout = scheduleConfig.getRequestTimeoutSeconds();
// ...
}
}
}
设计亮点
-
配置集中化:所有定时任务相关配置统一管理
-
动态配置:通过
CompositeConfigService支持运行时配置更新 -
线程安全:自定义线程池避免任务阻塞
-
可监控性:线程命名和日志记录便于问题排查
-
资源管理:正确的线程池关闭机制
注意事项
-
@SuppressWarnings("unused")用于抑制IDE警告,因为方法通过SpEL被调用 -
守护线程适合后台任务,但要注意任务可能被中断
-
线程池大小需要根据实际任务数量调整
这种配置方式特别适合需要动态调整执行策略的企业级应用。
3665

被折叠的 条评论
为什么被折叠?



