在控制台打印一句话,每隔一秒打印一次:
两步得到上述效果:
第一步:写一个测试类MyTimeTask继承TimerTask,并实现它的run()方法;
run主体打印一句话:System.out.println("hello:"+df.format(new Date()));
package cn.com.jsoft.task;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimerTask;
public class MyTimeTask extends TimerTask{
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("hello:"+df.format(new Date()));
}
public static void main(String[] args) {
/*SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(df.format(new Date()));*/
}
}
第二步:配置applicationContext-scheduler.xml(根据实际需求,自己命名)
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<bean id="myTimeTask" class="cn.com.jsoft.task.MyTimeTask"/>
<bean id="myTimeTaskJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="myTimeTask" />
</property>
<property name="targetMethod">
<value>run</value>
</property>
<property name="concurrent">
<value>false</value>
</property>
</bean>
<bean id="myTimeTaskTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"><!--如果项目报错,把CronTriggerBean换成CronTriggerFactoryBean -->
<property name="jobDetail">
<ref local="myTimeTaskJobDetail" />
</property>
<property name="cronExpression">
<!-- 每隔一分钟执行一次 -->
<!-- 0 */1 * * * ? -->
<value>*/1 * * * * ?</value>
</property>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false" autowire="no">
<property name="triggers">
<list>
<ref local="myTimeTaskTrigger" />
</list>
</property>
<property name="autoStartup">
<value>true</value>
</property>
</bean>
</beans>
说明:cronExpression参数配置(注意空格)
在线版:http://www.cronmaker.com/
<!-- 每隔一秒钟执行一次 -->
<value>*/1 * * * * ?</value>
<!-- 每隔一分钟执行一次 -->
<value>* */1 * * * ?</value>
从左到右分别是:秒,分,时,月的某天,月,星期的某天,年;其中年不是必须的,也就是说任何一个表达式最少需要六项。
先看示列:"0 0/30 8-10 5,20 * ?" 表示“每个月的5日和20日的8:00,8:30,9:00,9:30,10:00,10:30”
字符解释:
,:与,表式","两边的值都是需要执行的时间,如上例"5,20",每个月的5日与20日。
-:表示值的范围,如上例"8-10",从8点开始到10结束,包括8点与10点。
*:表式任意可合法的值,如上例"*"是处于月份的字段,所以代表1-12中的任意值,所以上例是指“每个月”。
/:增量,如上例是指从0分开始,每过30分钟取一次值。如果换成"5/8"就是从第5钟开始每过8分钟取一次值:8:05,8:13,8:21,8:29等等
?:不指定值,就是“我也不知道”的意思,只能出现在“月的某天,星期的某天”项中。在什么情况下用呢?如上例如果指定值为星期一,那么可能会出现如4月5日不是星期一,这里就是不对应,有冲突,所以指定为"?",也就是说我也不知道是星期几,只要是5日与20日就行了,至于是星期几我才不管呢!
L:最后的,last的意思,只能出现在“月的某天,星期的某天”项中。表示当前月或当前星期的最后一天,注意的是星期的最后一天为星期六。
W:月中最接近指定日期的普通日(星期一到星期五),只能出现在“月的某天”,如"15W"就是说当前月最接近15日的普通日,如果当月的15是星期三就是星期三,如果当月的15是星期六那么就是昨天也就是星期五,如果当月的15是星期天则为第二天也就是星期一。
#:当前月的第N个星期X日,只能出现在“星期的某天”项中。如"6#3"就是说当前月的第三个星期五,注意"1-7",1=星期天,2=星期一 等等。
(部分内容来自互联网)
"0 0 12 * * ?" 每天中午12点触发
"0 15 10 ? * *" 每天上午10:15触发
"0 15 10 * * ?" 每天上午10:15触发
"0 15 10 * * ? *" 每天上午10:15触发
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发
"0 15 10 15 * ?" 每月15日上午10:15触发
"0 15 10 L * ?" 每月最后一日的上午10:15触发
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发
对“concurrent”设置false的深入剖析:请看下面的例子与解答,来自http://www.iteye.com/problems/54435
、
========================================华丽的分隔符=================================================
今天重新照这个写的时候发现几个问题:
①好像SpringMVC-scheduler.xml需要配置到web.xml文件中,这没有说明,我这里补充下!
建议命名的时候取统一的前缀,比如楼主的:SpringMVC-scheduler.xml,SpringMVC-DB.xml,然后在web.xml中引用的时候:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMVC-*.xml</param-value>
</context-param>
②直接照着上面的代码复制粘贴,发现项目报错了:
Caused by: java.lang.IncompatibleClassChangeError: class org.springframework.scheduling.quartz.CronTriggerBean has
interface org.quartz.CronTrigger as super class
这个问题的解决办法是:把配置文件SpringMVC-scheduler.xml中的CronTriggerBean更换成CronTriggerFactoryBean,问题就解决了!
*************************************************************************************************************************************************
注解配置
1.在SpringMVC配置文件中添加
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.vrveis.roundTrip.task" />
如下图:
Demo:
package com.vrveis.roundTrip.task; 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框架配置定时任务"); } }
注意事项:
1、spring的@Scheduled注解 需要写在实现方法上
2、 定时器的任务方法不能有返回值(如果有返回值,spring初始化的时候会告诉你有个错误、需要设定一个proxytargetclass的某个值为true)
3、实现类上要有组件的注解@Component
扩展:定时时间的设置
如:“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 | , - * / |
通配符说明:
* 表示所有值. 例如:在分的字段上设置 "*",表示每一分钟都会触发。
? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。
例如:要在每月的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相同;
参考:
https://wuzhuti.cn/850.html/comment-page-1/
https://wuzhuti.cn/447.html