我通过以下方式在applicationcontext文件中定义了SchedulerFactoryBean:
<bean id="quartzscheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
<property name="autoStartup">
<value>true</value>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.scheduler.instanceName">MyClusteredScheduler</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
<prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop>
<prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
</props>
</property>
<property name="dataSource">
<ref bean="quartzdataSource" />
</property>
</bean>
<bean id="quartzdataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3305/quartz" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
这是我的工作类,它实际上是一个实体bean类,按以下方式定义:
@Entity
@Table(name = "DATABASEMONITOR")
public class DatabaseMonitor implements Serializable, Job {
@Id
@GeneratedValue
@Column(name = "ID", unique = true, nullable = false)
private Integer id;
@Column(name = "NAME", nullable = false)
private String name;
public DatabaseMonitor(String name, String sqlQuery){
this.name = name;
this.sqlQuery = sqlQuery;
}
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
System.out.println("inside job");
}
}
这是我的调度程序控制器类:
public class SchedulerController {
public static void addJob(DatabaseMonitor databaseMonitor){
JobDetail job = new JobDetail();
job.setName(databaseMonitor.getName());
job.setJobClass(DatabaseMonitor.class);
CronTrigger trigger = new CronTrigger();
trigger.setName(databaseMonitor.getName());
try {
trigger.setCronExpression("0/2 * * * * ?");
Scheduler scheduler = (Scheduler) BeansManager.getInstance().getBean("quartzscheduler");
scheduler.scheduleJob(job, trigger);
} catch (ParseException e) {
e.printStackTrace();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
从主类我调用这个调度函数来在运行时添加作业:
DatabaseMonitor databaseMonitor = new DatabaseMonitor(new Date().toString(), "query string");
SchedulerController.addJob(databaseMonitor);
现在问题是一切正常,没有任何异常,工作细节在预定义的石英数据库细节中得到更新 . 但这项工作没有得到执行 . 你能帮我解决这个问题吗?
2 回答
您的配置缺少必需的
org.quartz.threadPool.class
和org.quartz.threadPool.threadCount
属性 .见:http://quartz-scheduler.org/documentation/quartz-1.x/configuration/ConfigThreadPool
你的
DatabaseMonitor
应该有一个默认的构造函数 . Quartz将尝试执行JobDetail
. 并且JobDetail
将从头开始创建DatabaseMonitor
并执行其execute方法 . 由于DatabaseMonitor
没有默认构造函数,因此无法执行 .更新
既然你已经有了一个默认的构造函数,我建议稍微重构一下 . 我使用带有 spring 的2.2.1版石英,所以一些类名可能会有所不同 .
首先让你的实体分成两部分 .
我稍后会解释工作部分 . 然后让你的控制器重构为一个spring bean .
如您所见,我正在使用JobDataMap将参数传递给我的作业 . 这个参数可能是sqlQuery . 然后检查我们的工作 .
我正从上下文中读取我的查询 . 我的工作不包含任何州 . 在您的实施中,您的工作也是一个实体 . Hibernate(或其他JPA实现)代理几乎所有东西,并拥有很多状态 . 这会因石英执行而中断 .
更新2
我创建了一个示例应用程序并将其放到github .