分享

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

 nacy2012 2015-01-13

1、编写Job任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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、编写定时调用服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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、启动控制台日志

1
2
3
4
5
6
7
8
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、执行任务时错误

1
2
3
4
5
6
7
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方法后

1
2
3
4
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、解决方案

1
2
3
4
<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配置并未调用,对象注入会失败。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约