现在有一个应用需要定时做一些动作,使用的是quartz+spring,但是没有使用spring实现的quartz,这里发现了一个问题,就是通过spring注入进来的bean用于做为quartz的job时,无法保留该job已经通过spring注入好的属性,quartz会根据注入类完全new一个类,如下,我的job类:
public class SendMsgJob implements Job {
private SenderThread senderThread;
@Override
public void execute(JobExecutionContext paramJobExecutionContext) throws JobExecutionException {
System.out.println(senderThread);
}
public void setSenderThread(SenderThread senderThread) {
this.senderThread = senderThread;
}
public SenderThread getSenderThread() {
return senderThread;
}
}
任务实现类中需要一个发送消息的线程,在这里需要被注入,在spring中有该bean的配置,我在Trigger中还可以获取得到该属性senderThread,实现代码如下:
public class SendTrigger {
Logger log = LoggerFactory.getLogger(SendMsgJob.class);
List<Object> jobList;
public void init() throws Exception {
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
if (jobList == null) {
return;
}
String group = "group1";
for (int i = 0; i < jobList.size(); i++) {
//这里能够打出获取到属性值,说明注入成功
System.out.println(((Job) jobList.get(i)).getSenderThread())
//可是这里注册为job时候,传入的是class,quartaz在启动的时候是重新new了一个对象,因而原来已有属性值全部没了
JobDetail job = newJob(((Job) jobList.get(i)).getClass()).withIdentity("job" + i, group).build();
CronTrigger trigger = newTrigger().withIdentity("trigger" + i, group).withSchedule(cronSchedule("0 0/1 * * * ?")).build();
sched.scheduleJob(job, trigger);
}
// 启动定时任务
sched.start();
}
public void setJobList(List<Object> jobList) {
this.jobList = jobList;
}
}
spring中的配置如下:
<!--定时器任务配置(开始)-->
<bean id="trigger" class="automan.timer.job.SendTrigger" init-method="init">
<property name="jobList">
<list>
<ref local="sendMsgJob"></ref>
</list>
</property>
</bean>
<!-- 定时发送的任务 -->
<bean id="sendMsgJob" class="automan.timer.job.SendMsgJob">
<property name="senderThread">
<ref local="senderThread"></ref>
</property>
</bean>
<!--定时器任务配置(结束)-->
查看了它创建一个新的任务的源码,暂时还没有找到解决方案,网上搜索都是使用的spring封装好的quartz,也没有找到有人提相同的问题,是我实现上的问题,还是什么原因?再找找原因,既然spring能够实现,那我相信肯定有办法解决的。
后记:
后面还是选择了spring对quartz的封装使用,使用的方式如下:
<!--定时器任务配置(开始)-->
<!--配置JOB-->
<bean id="scheduledSendMsgJob"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="sendMsgJob" />
<property name="targetMethod" value="execute" />
</bean>
<!--配置Trigger-->
<bean id="sendMsgJobTrigger"
class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="scheduledSendMsgJob" />
<property name="startDelay" value="10000" />
<!-- 每1分钟执行一次 -->
<property name="repeatInterval" value="60000" />
</bean>
<!--配置Scheduler-->
<bean id="schedulerFactory"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean" autowire="no">
<property name="triggers">
<list>
<ref bean="sendMsgJobTrigger" />
</list>
</property>
<property name="autoStartup" value="true"/>
</bean>
<bean id="sendMsgJob" class="automan.timer.job.SendMsgJob">
<property name="senderThread">
<ref local="SenderThread"></ref>
</property>
</bean>
<!--定时器任务配置(结束)-->
不过需要注意一点的是,spring与quartz的版本配合:
spring 2.5.5 配 quartz 1.7.x
spring 2.5.6 配 quartz 1.8.x
sprint 3.x 配 quartz 2.x
本文出自:冯立彬的博客