Quartz 2.1.5学习笔记

        简单的了解了一下Quartz,发现实现定时任务有两种方法:一种是实现接口,一种是配置文件。

一、实现接口

package cn.manmanda.api.jobs;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.manmanda.core.news.utils.Global;
import static org.quartz.JobBuilder.*;
import static org.quartz.TriggerBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*;

/**
 * 定时任务
 * @date 2017-08-17
 * @author ericzhan1993
 * @version 1.0
 */
public class QuartzJobUtil implements Job{
	
	// 使用quartz, 需要被实例化, 可以用SchedulerFactory来实现
	private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();// Scheduler的创建和管理
	private static Date date = new Date();

	/**
	 * 重写Job接口的方法
	 * 注意: 实现类一定要是public类, 不能是内部类, 不然会报无法实例化的错误
	 */
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {// 执行延时推送消息定时任务
		System.out.println("定时任务开始执行...");
	}
	
	/**
	 * 新增任务
	 * @date 2017-08-17
	 * @author ericzhan1993
	 * @version 1.0
	 */
	public static void addJob() {// 添加一个延时任务
		try {
			Scheduler sched = gSchedulerFactory.getScheduler();// 得到调度器实例化Scheduler
			// 注: 2.x.x版本的quartz和1.x.x版本的调用接口不一样
			// 创建具体任务: 参数: (实现Job接口的类, 任务名, 任务组名)
			JobDetail jobDetail = newJob(QuartzJobUtil.class).withIdentity("jobname", "jobInGroupName").build();
			// 创建触发器: 绑定job和sched并设置一些参数, 一些方法参考api: http://www.quartz-scheduler.org/api/2.1.7/index.html
			// 每隔1秒, 执行一次, 永久重复执行
			Trigger trigger = newTrigger().withIdentity("jobname", "jobInGroupName").startNow().withSchedule(simpleSchedule()
				.withIntervalInSeconds(1).repeatForever()).build();
			// 设置触发器名和触发器组名, 供查询
			trigger.getTriggerBuilder().withIdentity("triggerName", "triggerInGroupName");
			// 规定在某时间执行, 可以用来做延迟任务
			// time单位: 毫秒	延迟10秒
			date.setTime(date.getTime() + 10 * 1000);
			SimpleTrigger trigger2 = (SimpleTrigger) newTrigger().withIdentity("jobname", "jobInGroupName").startAt(date).build();
			sched.scheduleJob(jobDetail, trigger);
//			sched.scheduleJob(jobDetail, trigger2);
			sched.start();// 执行
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
    public static void main(String[] args) {
    	addJob();
    }
	
}

因为时间的关系,只写了增加,别的以后补上。

1. 遇到的坑

①. 类无法被实例化

org.quartz.SchedulerException: Problem instantiating class ‘xxx’

本来想图个省事,弄个内部类实现接口,运行的时候发现报错,查官方文档发现:实现Job接口的类必须是public的

 

②. spring注入失败:在重写的方法中无法调用service方法

 java.lang.NullPointerException
    at cn.manmanda.api.jobs.QuartzJobUtil.execute(QuartzJobUtil.java:49)

错误指向的是service接口引用的方法,可能是因为实现Job接口的execute()重写导致spring @Autowired注解注入的变量无法使用,在网上找了一些方法,是需要手动注入spring+配置xml(bean)的,我觉得非常麻烦,一定有更好的方法,于是我尝试了JobDataMap类,把spring注入成功的service变量传入execute(),结果成功了,不过还是期待更简洁的方法,如果有可以告诉我。

// dataMap的使用
JobDataMap dataMap = jobDetail.getJobDataMap();
dataMap.put("key", valueObj);// 创建job时使用
Object obj = (Object)context.getJobDetail().getJobDataMap().get("key");// 重写Job接口时使用

 

二、配置文件

<?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"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	<!-- 使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法 -->
	<!-- 让spring来自动管理quartz -->
	<bean id="schedulerFactoryBean" name="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
		<property name="triggers">
            <list>
                <ref bean="myTriggersA"></ref>
                <ref bean="update"></ref>
                <ref bean="update1"></ref>
               <!--  <ref bean="update2"></ref> -->
            </list>
        </property>
        <property name="autoStartup" value="true"></property>
	</bean>
	
	<!-- quartz类型 -->
	<bean id="myTriggersA" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
		<!-- 配置JobDetail类 -->
		<property name="jobDetail" ref="myJobDetailA" />
		<property name="cronExpression">
			<value>0 0 0 * * ?</value><!-- 配置定时时间 -->
		</property>
	</bean>
	<bean id="myJobDetailA" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<!-- 配置你的实现类 -->
		<property name="targetObject" ref="myJobA"></property>
		<!-- 配置你的实现方法 -->
		<property name="targetMethod" value="work"></property>
		<property name="concurrent" value="false" />
	</bean>
	<bean id="myJobA" class="cn.manmanda.api.jobs.IndentJob"></bean>
</beans> 

然后你的实现类:

public class IndentJob {
	public void work(){
		// 代码逻辑
		// 按照配置文件的类和方法自动执行
	}
}

 

转载于:https://my.oschina.net/NamiZone/blog/1512358

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值