Quartz定时调用处理问题(Spring注入方式)

1、编写Job任务

package com.kvt.lbs.alarm.entity;

import java.util.List;
import javax.annotation.Resource;
import org.quartz.Job;
import org.quartz.JobExecutionContext; 
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.kvt.lbs.alarm.dao.AlarmDao;
import com.kvt.lbs.utils.Log;
/**
 * 报警定时任务
 * <li>文件名称: AlarmJob</li> 
 * <li>文件描述: $报警定时任务</li> 
 * <li>内容摘要: 包括任务执行方法和执行频率</li>
 * <li>完成日期:2013-6-17</li> 
 * <li>修改记录1:boonya</li>
 *
 */
@Component("alarmJob")
public class AlarmJob implements Job
{
	@Resource
	private AlarmDao alarmDao;

	@Transactional(propagation = Propagation.REQUIRED)
	public void execute(JobExecutionContext jbec) throws JobExecutionException
	{
		// doFlag处理类型:0未处理,1已处理,2过期处理
		// operateWay操作方式:1手动过期,2系统过期
		int doFlag=2,operateWay=2;
		boolean isSuccess=true;
		String operator = "定时任务", remark = "系统定时过期处理";
		Log.getLogger(this.getClass()).info("==Start====报警数据:系统过期处理-----------开始");
		String[] deviceIdToalarmTypeArray = this.getDeviceIdToAlarmTypekeys();
		if (deviceIdToalarmTypeArray.length>0)
		{
			isSuccess= alarmDao.handleAlarmByOvertime(deviceIdToalarmTypeArray,doFlag,operateWay, operator, remark);
		}
		Log.getLogger(this.getClass()).info("==Results==报警数据:系统过期处理" + (isSuccess ? "成功" : "失败")+" ,处理数据条数: "+deviceIdToalarmTypeArray.length);
		Log.getLogger(this.getClass()).info("==End======报警数据:系统过期处理-----------完成");
	}

	/**
	 * 获取内存中需要过期处理的报警的Key数组
	 * 
	 * @return
	 */
	public String[] getDeviceIdToAlarmTypekeys()
	{
		String[] deviceIdToalarmTypeArray = new String [0];
		long longDeTime = 1 * 24 * 60 * 60 * 1000;// 24小时后过期
		List<String> list = alarmDao.getOvertimeDeviceIdToAlarmTypeKeys(longDeTime);
		if (list != null)
		{
			deviceIdToalarmTypeArray = new String[list.size()];
			for (int i = 0; i < list.size(); i++)
			{
				deviceIdToalarmTypeArray[i] = list.get(i);
			}
		}
		return deviceIdToalarmTypeArray;
	}

}

2、编写定时调用服务

package com.kvt.lbs.alarm.service;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.stereotype.Component;
import com.kvt.lbs.alarm.entity.AlarmJob;
import com.kvt.lbs.utils.Log;
/**
 * 报警定时任务服务
 *  <li>文件名称: AlarmJobService</li> 
 *  <li>文件描述: $报警过期处理</li>
 *  <li>内容摘要: 启动报警过期定时任务</li> 
 *  <li>完成日期:2013-5-29</li> 
 *  <li>修改记录1:boonya</li>
 * 
 */
@Component("alarmJobService")
public class AlarmJobService
{
	public void start()
	{
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = null;
		try
		{
			Log.getLogger(this.getClass()).info("==Start==告警过期处理定时任务启动===========");
			scheduler = sf.getScheduler();

			JobDetail job = new JobDetail("alarmJob", "alarm", AlarmJob.class);
			Trigger trigger = TriggerUtils.makeDailyTrigger("alarmTrigger", 23, 59);// 每天23:59分执行任务
			scheduler.resumeJob("alarmJob", "alarmJob");
			scheduler.resumeJobGroup("alarm");
			scheduler.scheduleJob(job, trigger);
			scheduler.start(); 
			Log.getLogger(this.getClass()).info("==End==告警过期处理定时任务启动成功========");
		} catch (Exception e)
		{
			try
			{
				Log.getLogger(this.getClass()).info("==Exception==告警过期处理:"+e.getMessage());
				scheduler.shutdown(true);
				Log.getLogger(this.getClass()).info("==End==告警过期处理:异常停止!");
			} catch (SchedulerException e1)
			{
				Log.getLogger(this.getClass()).info("==Exception==告警过期处理:"+e1.getMessage());
			}
		}
	}

}

3、启动控制台日志

2013-07-30 14:43:28 [ localhost-startStop-1:6812 ] - [ INFO ] ==Start==告警过期处理定时任务启动===========
2013-07-30 14:43:28 [ localhost-startStop-1:6812 ] - [ INFO ] Job execution threads will use class loader of thread: localhost-startStop-1
2013-07-30 14:43:28 [ localhost-startStop-1:6828 ] - [ INFO ] Quartz Scheduler v.1.6.0 created.
2013-07-30 14:43:28 [ localhost-startStop-1:6828 ] - [ INFO ] RAMJobStore initialized.
2013-07-30 14:43:28 [ localhost-startStop-1:6828 ] - [ INFO ] Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties'
2013-07-30 14:43:28 [ localhost-startStop-1:6828 ] - [ INFO ] Quartz scheduler version: 1.6.0
2013-07-30 14:43:28 [ localhost-startStop-1:6828 ] - [ INFO ] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
2013-07-30 14:43:28 [ localhost-startStop-1:6828 ] - [ INFO ] ==End==告警过期处理定时任务启动成功========

4、执行任务时错误

2013-07-30 15:09:00 [ DefaultQuartzScheduler_Worker-1:80078 ] - [ INFO ] ==Start====报警数据:系统过期处理-----------开始
2013-07-30 15:09:25 [ DefaultQuartzScheduler_Worker-1:105156 ] - [ ERROR ] Job alarm.alarmJob threw an unhandled Exception: 
java.lang.NullPointerException
	at com.kvt.lbs.alarm.entity.AlarmJob.getDeviceIdToAlarmTypekeys(AlarmJob.java:55)
	at com.kvt.lbs.alarm.entity.AlarmJob.execute(AlarmJob.java:37)
	at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:529)

5、去掉AlarmJob中的getDeviceIdToAlarmTypekeys方法后

INFO: Server startup in 13429 ms
2013-07-30 15:42:00 [ DefaultQuartzScheduler_Worker-1:77782 ] - [ INFO ] ==Start====报警数据:系统过期处理-----------开始
2013-07-30 15:42:00 [ DefaultQuartzScheduler_Worker-1:77782 ] - [ INFO ] ==Results==报警数据:系统过期处理成功 ,处理数据条数: 0
2013-07-30 15:42:00 [ DefaultQuartzScheduler_Worker-1:77782 ] - [ INFO ] ==End======报警数据:系统过期处理-----------完成
6、发现问题所在

getDeviceIdToAlarmTypekeys方法内部逻辑有误,但具体不知道是哪一行或那几行,但是可以肯定的是这里出了错,一定是这里最后测试发现:alarmDao为null,对象注入失败。

7、解决方案

<bean id="helpDao" class="com.kvt.lbs.help.dao.HelpDao"></bean>
<bean id="helpService" class="com.kvt.lbs.help.service.HelpService"></bean>
<bean id="alarmDao" class="com.kvt.lbs.help.dao.AlarmDao"></bean>
<bean id="alarmService" class="com.kvt.lbs.help.service.AlarmService"></bean>

这样就可以注入对象了。

8、注意事项

定时任务不要写在static代码块中。因为服务器启动的时候,jvm启动时static块一起被初始化,此时Spring配置并未调用,对象注入会失败。

转载于:https://my.oschina.net/boonya/blog/148424

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值