本篇文章主要介绍了 Java web 项目中编写定时任务的实现, 具有一定的参考价值, 有兴趣的可以了解一下
之前在的公司有专门的任务调度框架, 需要使用的时候引个 jar 包加个配置和注解就可以使用了, 还有专门的平台来维护运行的机器及监控执行状态等等
现在突然没了这个工具, 而又要写定时任务, 该怎么办呢?
对于非 Web 应用来说, 我们可以使用 Quartz, 使用简单, 功能强大
对于 Java Web 应用来说, 当然也可以使用 Quartz(有一篇介绍了方法:/article/17/1108/358686.html), 但是还有更方便的工具, 那就是 spring 自带的支持定时任务功能
Spring 的定时任务在 spring-context 中, 简单配置的模板如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:task="http://www.springframework.org/schema/task"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
- http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
- <task:scheduler id="scheduler" pool-size="200"/>
- <task:scheduled-tasks>
- <!-- 你的 task -->
- <task:scheduled ref="xxxTask" method="execute" cron="0 0 * * * ?"/>
- </task:scheduled-tasks>
- <task:annotation-driven scheduler="scheduler"/>
- </beans>
其中 task:scheduler 指定了执行定时任务使用的 scheduler, 默认使用的是
org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
task:annotation-driven 允许使用 @Async 和 @Scheduled 注解;
task:scheduler-tasks 中定义了一个个 task, 其中执行周期可以使用 cron 表达式, 还可指定延时或频率等方式
接下来还有一个问题, 通常我们的线上环境是集群环境, 有多台机器, 而这些定时任务通常只需要在一台上执行, 如何来进行控制呢?
目前想到两种办法, 分享给大家:
1. 使用 Redis 全局缓存
/article/17/0310/322306.html
2. 通过判断文件的方式
通过判断某文件是否存在, 来决定是否执行任务(是否加载任务对应的 spring 配置文件), 参考代码:
- @Component
- public class XxxListener implements ApplicationContextAware {
- // 防止加载多次
- private static final AtomicInteger INIT_LOCK = new AtomicInteger(0);
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- if (INIT_LOCK.incrementAndGet() > 1) {
- // 类已加载过
- return;
- }
- Resource resource = applicationContext.getResource("classpath:<标识文件>");
- if (!resource.exists()) {
- // 文件不存在, 不启动
- return;
- }
- ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(applicationContext);
- context.setConfigLocations("classpath:spring/job.xml");
- context.refresh();
- }
- }
来源: http://www.phperz.com/article/18/0225/358682.html