Java Web项目之添加定时任务

文章目录

    • 一、使用监听器注入
        • (1)创建监听器类:(示例代码)
        • (2)创建定时任务类:(示例代码)
        • (3)创建TimerTask类:(示例代码)
        • (4)在web.xml注册监听器:(示例代码)
    • 二、使用spring注解注入
        • (1)在SpringMVC配置文件(applicationContext.xml)中添加
        • (2)示例Demo:
        • (3)注意事项:
        • (4)扩展:定时时间的设置
        • (5)通配符说明:

在Java Web程序中加入定时任务,这里介绍两种方式:1.使用监听器注入;2.使用Spring注解@Scheduled注入。
推荐使用第二种形式。

一、使用监听器注入

(1)创建监听器类:(示例代码)

Java Web项目之添加定时任务_第1张图片

package com.gx.job;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class TimerDataTaskListener implements ServletContextListener{

	@Override
	public void contextInitialized(ServletContextEvent sce) {
		new TimerManager();
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		// TODO Auto-generated method stub
	}

}

(2)创建定时任务类:(示例代码)

Java Web项目之添加定时任务_第2张图片

package com.gx.job;

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;

public class TimerManager {
	// 时间间隔:24h
	private static final long PERIOD_DAY = 24 * 60 * 60 * 1000;

	public TimerManager() {
		Calendar calendar = Calendar.getInstance();

		// 定制每日12:30:30执行
		calendar.set(Calendar.HOUR_OF_DAY, 12);
		calendar.set(Calendar.MINUTE, 30);
		calendar.set(Calendar.SECOND, 30);

		Date date = calendar.getTime(); // 第一次执行定时任务的时间
		// 如果当前时间已经过去所定时的时间点,则在第二天时间点开始执行
		if (date.before(new Date())) {
			date = this.addDay(date, 1);
		}
		Timer timer = new Timer();
		TimerTaskService task = new TimerTaskService();
		// 安排指定的任务在指定的时间开始进行重复的固定延迟执行。
		timer.schedule(task, date, PERIOD_DAY);
	}

	// 增加或减少天数
	private Date addDay(Date date, int num) {
		Calendar startDT = Calendar.getInstance();
		startDT.setTime(date);
		startDT.add(Calendar.DAY_OF_MONTH, num);
		return startDT.getTime();
	}
}

(3)创建TimerTask类:(示例代码)

Java Web项目之添加定时任务_第3张图片

package com.gx.job;

import java.util.TimerTask;

public class TimerTaskService extends TimerTask {

	@Override
	public void run() {
		try {
			// 要执行的任务逻辑写在这里
			System.out.println("执行成功");
		} catch (Exception e) {
			System.out.println("执行失败");
		}
	}
}

(4)在web.xml注册监听器:(示例代码)

Java Web项目之添加定时任务_第4张图片

<!-- TimerDataTaskListener 监听器 -->
<listener>
	<listener-class>com.gx.job.TimerDataTaskListener</listener-class>
</listener>

二、使用spring注解注入

这里以SSM框架(Spring + SpringMVC + Mybatis)为例:

(1)在SpringMVC配置文件(applicationContext.xml)中添加

xmlns:task="http://www.springframework.org/schema/task" 
http://www.springframework.org/schema/task  
http://www.springframework.org/schema/task/spring-task-3.2.xsd 

然后配置任务扫描:

<task:annotation-driven />

最后配置扫描任务位置

<context:component-scan base-package="com.gx.job"/>

如下图:
Java Web项目之添加定时任务_第5张图片

<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"  
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="
	http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
	http://www.springframework.org/schema/aop   
    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
	http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
	http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	http://www.springframework.org/schema/task 
	http://www.springframework.org/schema/task/spring-task-3.1.xsd ">
	
	<!-- 开启注解 -->
	<context:annotation-config />
	
	<!-- 开启定时任务 -->
	<task:annotation-driven/>
	
	<!-- 自动扫描 -->
	<context:component-scan base-package="com.gx.job"/>
	
</beans>

(2)示例Demo:

Java Web项目之添加定时任务_第6张图片

package com.gx.job;

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

@Component
public class FlightTrainTask {
	@Scheduled(cron = "0/5 * * * * ? ") // 间隔5秒执行
	public void taskCycle() {
		System.out.println("使用SpringMVC框架配置定时任务");
	}
}

(3)注意事项:

1、spring的@Scheduled注解 需要写在实现方法上。
2、 定时器的任务方法不能有返回值。(如果有返回值,spring初始化的时候会告诉你有个错误、需要设定一个proxytargetclass的某个值为true)
3、实现类上要有组件的注解@Component 。

(4)扩展:定时时间的设置

关于定时时间的设置方式如下:
  如:“0/5 * * * * ?”
  CronTrigger配置完整格式为: [秒] [分] [小时] [日] [月] [周] [年]

参考如下:

序号 说明 是否必填 允许填写的值 允许的通配符
1 0-59 , - * /
2 0-59 , - * /
3 0-23 , - * /
4 1-31 , - * ? / L W
5 1-12或JAN-DEC , - * /
6 1-7或SUN-SAT , - * ? / L W
7 empty或1970-2099 , - * /

(5)通配符说明:

* 表示所有值。例如:在分的字段上设置 “*”,表示每一分钟都会触发。

? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为"?" 具体设置为 0 0 0 10 * ? 。

- 表示区间。例如:在小时上设置 “10-12”,表示 10,11,12点都会触发。

, 表示指定多个值,例如:在周字段上设置 “MON,WED,FRI” 表示周一,周三和周五触发。

/ 用于递增触发。例如:在秒上面设置"5/15" 表示从5秒开始,每增15秒触发(5,20,35,50)。 在月字段上设置’1/3’所示每月1号开始,每隔三天触发一次。

L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]),在周字段上表示星期六,相当于"7"或"SAT"。如果在"L"前加上数字,则表示该数据的最后一个。例如在周字段上设置"6L"这样的格式,则表示“本月最后一个星期五"。

W 表示离指定日期的最近那个工作日(周一至周五)。例如:在日字段上设置"15W",表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发,如果15号是周未,则找最近的下周一(16号)触发,如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 “1W”,它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,“W"前只能设置具体的数字,不允许区间”-")。

# 序号(表示每月的第几个周几),例如在周字段上设置"6#3"表示在每月的第三个周六。注意如果指定"#5",正好第五周没有周六,则不会触发该配置(用在母亲节和父亲节再合适不过了) 。

小提示:
'L’和 'W’可以组合使用。如果在日字段上设置"LW",则表示在本月的最后一个工作日触发;
周字段的设置,若使用英文字母是不区分大小写的,即MON 与mon相同。

你可能感兴趣的:(Java)