在前端业务场景中,经常会遇到需要配合后端定时任务完成需求的情况,比如定时同步数据、定时推送提醒、定时执行批量操作等。Spring框架提供了完善的定时任务支持,结合前端JS的能力,可以实现灵活的前后端定时任务联动。

Spring定时任务基础配置
首先需要在Spring项目中开启定时任务功能,在配置类或者启动类上添加@EnableScheduling注解,然后定义定时任务方法,使用@Scheduled注解配置执行规则。
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@EnableScheduling
@Component
public class DemoScheduleTask {
// 每5秒执行一次
@Scheduled(cron = "0/5 * * * * ?")
public void demoTask() {
System.out.println("定时任务执行,当前时间:" + System.currentTimeMillis());
}
}
@Scheduled注解支持cron表达式、固定间隔、固定延迟等多种配置方式,开发者可以根据业务需求选择合适的配置。
JS调用接口触发/控制定时任务
如果前端需要主动触发、暂停或者修改定时任务的执行规则,需要在后端提供对应的接口,前端通过JS发起请求来控制。
后端提供控制接口
首先定义定时任务的控制逻辑,这里以动态控制定时任务的启用和暂停为例:
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/schedule")
public class ScheduleController {
// 定时任务开关标记
private volatile boolean taskEnabled = true;
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(5);
scheduler.initialize();
return scheduler;
}
// 动态定时任务
@Scheduled(cron = "0/5 * * * * ?")
public void dynamicTask() {
if (taskEnabled) {
System.out.println("动态定时任务执行,当前时间:" + System.currentTimeMillis());
}
}
// 开启定时任务接口
@PostMapping("/enable")
public String enableTask() {
taskEnabled = true;
return "定时任务已开启";
}
// 关闭定时任务接口
@PostMapping("/disable")
public String disableTask() {
taskEnabled = false;
return "定时任务已关闭";
}
}
前端JS调用接口
前端使用JS的fetch或者axios发起请求,调用后端的控制接口,示例代码如下:
// 开启定时任务
function enableSchedule() {
fetch('http://ipipp.com/schedule/enable', {
method: 'POST'
})
.then(response => response.text())
.then(data => {
console.log('操作结果:', data);
alert('定时任务已开启');
})
.catch(error => {
console.error('请求失败:', error);
});
}
// 关闭定时任务
function disableSchedule() {
fetch('http://ipipp.com/schedule/disable', {
method: 'POST'
})
.then(response => response.text())
.then(data => {
console.log('操作结果:', data);
alert('定时任务已关闭');
})
.catch(error => {
console.error('请求失败:', error);
});
}
JS监听定时任务执行结果
如果前端需要获取定时任务的执行结果,可以让后端将定时任务的执行结果存储到缓存或者数据库中,前端通过轮询或者长连接的方式获取结果。
后端存储任务结果
修改定时任务逻辑,将执行结果存储到缓存中:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class ResultScheduleTask {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 每10秒执行一次,存储结果到Redis
@Scheduled(cron = "0/10 * * * * ?")
public void taskWithResult() {
String result = "定时任务执行成功,执行时间:" + LocalDateTime.now();
// 存储结果,key为schedule_result,过期时间30秒
redisTemplate.opsForValue().set("schedule_result", result, 30, java.util.concurrent.TimeUnit.SECONDS);
System.out.println(result);
}
}
前端轮询获取结果
前端通过定时轮询接口获取最新的任务执行结果:
// 轮询获取定时任务结果
function pollScheduleResult() {
setInterval(() => {
fetch('http://ipipp.com/schedule/result')
.then(response => response.text())
.then(data => {
if (data) {
console.log('最新定时任务结果:', data);
document.getElementById('result-container').innerText = data;
}
})
.catch(error => {
console.error('获取结果失败:', error);
});
}, 3000); // 每3秒轮询一次
}
// 页面加载后启动轮询
window.onload = function() {
pollScheduleResult();
};
配合使用的注意事项
- 跨域问题:如果前后端分离部署,需要后端配置跨域支持,否则JS请求会被拦截。
- 任务幂等性:定时任务的逻辑需要保证幂等,避免重复执行导致数据异常。
- 接口安全:控制定时任务的接口需要添加权限校验,避免被恶意调用。
- 性能问题:高频的定时任务需要考虑线程池配置,避免占用过多系统资源,前端轮询间隔也不宜过短。
JavaScriptSpring定时任务前后端交互定时任务触发接口调用修改时间:2026-06-12 06:54:17