spring中定时任务的多种实现
本文主要是记录工作中所遇到的情况,并非教学!!!
一、通过spring自带的@Scheduled注解实现定时任务
1.更改ApplicationContext-mvc.xml/spring.xml 等配置文件,如果不知道自己应该配置哪个文件的话去web.xml中找到<servlet>标签中的配置文件去配置就行(因为我试过配置在<context-param>标签下的ApplicationContext.xml里面会报错)
文件中需要更改的内容如下:
(1)xmlns:task="http://www.springframework.org/schema/task"
(2)xsi:schemaLocation中添加 (其中spring-task-3.1.xsd的版本可以更改看你的spring版本)具体参考下图
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd
1 <beans xmlns="http://www.springframework.org/schema/beans"
2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xmlns:context="http://www.springframework.org/schema/context"
4 xmlns:aop="http://www.springframework.org/schema/aop"
5 xmlns:mvc="http://www.springframework.org/schema/mvc"
6 xmlns:task="http://www.springframework.org/schema/task"
7 xsi:schemaLocation="http://www.springframework.org/schema/beans
8 http://www.springframework.org/schema/beans/spring-beans.xsd
9 http://www.springframework.org/schema/aop
10 http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
11 http://www.springframework.org/schema/context
12 http://www.springframework.org/schema/context/spring-context.xsd
13 http://www.springframework.org/schema/mvc
14 http://www.springframework.org/schema/mvc/spring-mvc.xsd
15 http://www.springframework.org/schema/task
16 http://www.springframework.org/schema/task/spring-task-3.1.xsd">
(3)添加 task标签设置 ,可以详细配置也可以直接默认
多的部分是对与线程池的设置,配置线程池后如果多个定时任务同时执行也没问题,不配置的话spring默认是单线程模式
1 <!--形式一-->
2 <task:executor id="executor" pool-size="5" />
3 <task:scheduler id="scheduler" pool-size="10" />
4 <task:annotation-driven executor="executor" scheduler="scheduler" />
5
6
7 <!--形式二-->
8 <task:annotation-driven />
(4)不要忘记配置你要执行的自动化程序所在的包的路径,将该包的路径加入扫描(按照自身实际情况配置)
<context:component-scan base-package="com.project.*" />
2.创建你的定时任务程序
1 /**
2 * @author
3 * @Time 2020-07-08 17:07
4 */
5 //必须添加注解交由spring管控才能生效
6 @Component
7 public class ScheduledDemo {
8 //由于将整个类交由spring管控不必担心@Autowired注解失效的情况
9 @Autowired
10 private TestService testService;
11
12 //有点缺点该注解只支持6位参数的cron表达式不支持7位的
13 @Scheduled(cron = "0 0/1 * * * ? ")
14 public void aaa(){
15 //实现你需要的方法即可
16 testService.XXX();
17 System.out.println("哈哈哈哈");
18 }
19
20 }
二、通过quartz组件实现定时任务(有点问题按照网上的方法最后我也没成功纳入spring管理。。。)
1.通过官网下载quartz ,下载完成是下图的压缩包 解压后相应目录下有你需要的jar包,自行导入即可(其他的都是依赖jar包,最低情况只需要导入quartz自身的两个jar就行)
配置一下日志打印(依赖于log4j组件)
2.此处就不讲quartz怎么使用了,结合网上的分享,这里提供一个工具类方便直接调用
1 /** 2 * @author 3 * @Time 2020-07-06 17:00 4 */ 5 public class SchedulerUtil { 6 private static Logger logger = Logger.getLogger(SchedulerUtil.class);// log4j记录日志 7 /** 8 * [简单任务调度:每次执行间隔为多少毫秒,执行多少次] <br> 9 * @param jobName 任务名字 10 * @param jobGroupName 任务组名字 11 * @param triggerName 触发器名字 12 * @param triggerGroupName 触发器组名字 13 * @param jobClass 任务类 14 * @param time 时间间隔 15 * @param count 执行几次<br> 16 */ 17 public static void handleSimpleTrigger(String jobName, String jobGroupName, 18 String triggerName, String triggerGroupName, Class jobClass, 19 int time, int count) {28 // 通过schedulerFactory获取一个调度器 29 SchedulerFactory schedulerfactory = new StdSchedulerFactory(); 30 Scheduler scheduler = null; 31 try { 32 // 通过schedulerFactory获取一个调度器 33 scheduler = schedulerfactory.getScheduler(); 34 // 创建jobDetail实例,绑定Job实现类 35 // 指明job的名称,所在组的名称,以及绑定job类 36 JobDetail job = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build(); 37 // 定义调度触发规则 38 //使用simpleTrigger规则 39 Trigger trigger=TriggerBuilder.newTrigger().withIdentity(triggerName,triggerGroupName) 40 .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(time).withRepeatCount(count)) 41 .build(); 42 // 把作业和触发器注册到任务调度中 43 scheduler.scheduleJob(job, trigger); 44 // 启动调度 45 scheduler.start(); 46 } catch (Exception e) {48 logger.error("执行"+jobName+"组"+jobName+"任务出现异常E:["+ e.getMessage() + "]"); 49 } 50 } 51 /** 52 * [复杂任务调度:每天几点几分几秒定时执行任务] <br> 53 * @param jobName 任务名字 54 * @param jobGroupName 任务组名字 55 * @param triggerName 触发器名字 56 * @param triggerGroupName 触发器组名字 57 * @param jobClass 任务类 58 * @param cron 触发规则<br> 59 */ 60 /** 61 * 62 * 63 */ 64 public static void hadleCronTrigger(String jobName, String jobGroupName, 65 String triggerName, String triggerGroupName, Class jobClass,String cron) {73 // 通过schedulerFactory获取一个调度器 74 SchedulerFactory schedulerfactory = new StdSchedulerFactory(); 75 Scheduler scheduler = null; 76 try { 77 // 通过schedulerFactory获取一个调度器 78 scheduler = schedulerfactory.getScheduler(); 79 // 创建jobDetail实例,绑定Job实现类 80 // 指明job的名称,所在组的名称,以及绑定job类 81 JobDetail job = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build(); 82 // 定义调度触发规则 83 //使用cornTrigger规则 每天18点30分 84 Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName) 85 .withSchedule(CronScheduleBuilder.cronSchedule(cron)) 86 .build(); 87 // 把作业和触发器注册到任务调度中 88 scheduler.scheduleJob(job, trigger); 89 // 启动调度 90 scheduler.start(); 91 } catch (Exception e) {93 logger.error("执行" + jobName + "组" + jobName + "任务出现异常E:[" + e.getMessage() + "]"); 94 } 95 } 96 }
3.方式一 :创建自己的job类,然后通过@PostConstruct注解在项目启动后调用(配合第二条使用)
/** * @author * @Time 2020-07-06 17:40 */ @DisallowConcurrentExecution //不允许job并发执行,防止重复调用,只对于同一实例有效,不同jobDetails引用同一个job时不起作用 public class TPersonFollowUpJob implements Job { @Autowired private TestService testService; @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { //因为没有被纳入spring管理,所以这里通过这个方法实现调用spring管理的组件让该页面的@Autowired 注解生效 SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); //自己要实现的方法 testService.XXX(); System.out.println("哈哈哈哈"); } }
下面是调用方法
//该注解保证了该方法可以在程序启动后自动调用执行一次 @PostConstruct public void start(){ //这里使用我们前面定义好的工具类来调用我们的Job方法类,这里的cron表达式支持最多7位参数 SchedulerUtil.hadleCronTrigger("任务名字", "任务组名字","触发器名字", "触发器组名字", TPersonFollowUpJob.class,"0 0/1 * * * ? *"); }
4.方式二 :直接通过spring的xml配置完成(在web.xml的<context-param>标签下的ApplicationContext.xml中进行配置,别的位置会报错),独立使用
1 <!--定时器任务配置(开始) --> 2 <!--配置JOB --> 3 <!--TPersonFollowUpTasksService这个bean是为了指定你早已经写好的为了定时执行的方法所在的实现类 --> 4 <bean id="TPersonFollowUpTasksService" class="com.msunsoft.service.personMana.Impl.TPersonFollowUpTasksServiceImpl"></bean> 5 <bean id="JobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 6 <property name="targetObject"> 7 <ref bean="TPersonFollowUpTasksService" /> 8 </property> 9 <property name="targetMethod"> 10 <!--在这里指定需要定时执行的方法名--> 11 <value>createFollowUpTasks</value> 12 </property> 13 <property name="concurrent"> 14 <value>false</value> 15 </property> 16 </bean> 17 <!--配置Trigger --> 18 <bean id="deleteDataTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> 19 <property name="jobDetail"> 20 <ref bean="JobDetail" /> 21 </property> 22 <property name="cronExpression"> 23 <!-- 这里支持7个参数的corn表达式 每个小时的每分钟执行一次 --> 24 <value>0 0/1 * * * ? *</value> 25 </property> 26 </bean> 27 <!--配置Scheduler --> 28 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false" autowire="no"> 29 <property name="triggers"> 30 <list> 31 <ref bean="deleteDataTrigger" /> 32 </list> 33 </property> 34 <property name="autoStartup"> 35 <value>true</value> 36 </property> 37 </bean> 38 <!--定时器任务配置(结束) -->