修改:我正在使用quartz-2.1.5.jar
。以下是我的课程摘要:
HttpPollingJob
扩展PollingJob
扩展ScheduledJob
实现org.quartz.Job
具体做法是:
1)ScheduledJob
实现Quartz Job
(我所有Job
类型的抽象基类):
import org.quartz.Job;
import org.quartz.Trigger;
public abstract class ScheduledJob implements Job {
private Trigger trigger;
public ScheduledJob() {
this(null);
}
public ScheduledJob(Trigger trig) {
super();
if(trig == null)
trig = getDefaultTrigger();
setTrigger(trig);
}
public Trigger getTrigger() {
return trigger;
}
public void setTrigger(final Trigger trig) {
trigger = trig;
}
protected abstract Trigger getDefaultTrigger();
}
2)PollingJob
扩展ScheduledJob
- 所有“轮询器”以特定频率轮询某些资源/端点:
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import com.me.jobs.ScheduledJob;
public abstract class PollingJob extends ScheduledJob {
private static long DEF_FREQUENCY = 10 * 1000; // 10 secs
private String name;
private long frequency;
public PollingJob(final String nm) {
this(nm, DEF_FREQUENCY);
}
public PollingJob(final String nm, final long freq) {
super();
setName(nm);
setFrequency(freq);
}
public abstract void poll(JobExecutionContext context);
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
poll(context);
}
public String getName() {
return name;
}
public void setName(final String nm) {
name = nm;
}
public long getFrequency() {
return frequency;
}
public void setFrequency(final long freq) {
frequency = freq;
}
protected final Trigger getDefaultTrigger() {
TriggerBuilder<?> triggerBuilder = TriggerBuilder.newTrigger()
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMilliseconds(DEF_FREQUENCY));
return triggerBuilder.build();
}
}
3)HttpPollingJob
扩展PollingJob
- “HTTP pollers”轮询一个Web服务器(使用HTtpClient):
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.quartz.JobExecutionContext;
import com.me.MonitoredEvent;
import com.me.MonitoredEventRegistrar;
public class HttpPollingJob extends PollingJob {
private String serverURL;
private org.slf4j.Logger logger =
org.slf4j.LoggerFactory.getLogger(HttpPollingJob.class);
public HttpPollingJob(final String nm, final String server) {
super(nm);
setServerURL(server);
}
public String getServerURL() {
return serverURL;
}
public void setServerURL(final String server) {
serverURL = server;
}
@Override
public final void poll(JobExecutionContext context) {
MonitoredEvent event = null;
try {
// This is where we would use HttpClient to connect to a web server and poll it.
System.out.println("Job fired!");
}
catch(Throwable thrown) {
logger.error(thrown.getMessage());
}
}
}
4)JobDriver
- 定义了几个HttpPollingJob
并使用Quartz启动它们:
public class JobDriver {
private List<HttpPollingJob> jobs;
public JobDriver() {
HttpPollingJob job1 = new HttpPollingJob("job-1", "http://www.example.com/1");
HttpPollingJob job2 = new HttpPollingJob("job-2", "http://www.example.com/2");
HttpPollingJob job3 = new HttpPollingJob("job-3", "http://www.example.com/3");
jobs = new ArrayList<HttpPollingJob>();
jobs.add(job1);
jobs.add(job2);
jobs.add(job3);
}
public static void main(String[] args) {
JobDriver driver = new JobDriver();
driver.startJobs();
}
private void startJobs() {
try {
// Obtain a basic SchedulerFactory and fire it up.
SchedulerFactory schedulerFactory = new org.quartz.impl.StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
// Define a job for every declared monitor.
JobBuilder jobBuilder = null;
for(ScheduledJob job : jobs) {
Trigger trigger = job.getTrigger();
jobBuilder = JobBuilder.newJob(job.getClass());
// Bind the current job to this trigger.
scheduler.scheduleJob(jobBuilder.build(), trigger);
// TODO: Shut the scheduler down politely?!?!
}
catch(Throwable exc) {
logger.error(exc.getMessage());
// Force application to kick out.
throw new RuntimeException(exc);
}
}
}
当我运行此代码时,我得到一个完美的启动,没有错误或运行时异常。如果我撒上System.out.println
语句,我可以看到每一行代码执行完美无缺。唯一的问题是,一旦程序运行,它就不会打印“ Job fired!”消息,表明轮询工作正在开始。
我已经尝试了start()
和shutdown()
的每一种组合,我认为无济于事。任何Quartz专家都可以查看这段代码并告诉我为什么这个工作没有解雇?
在日志中(我配置了log4j),我看到为计划作业创建了Quartz工作线程。我觉得我99%的路在那里,但我只是错过了一些明显的东西。提前谢谢!
答案 0 :(得分:12)
@ 4herpsand7derpsago是的你是对的,你是99%,我运行你的代码,其中只有一个问题,HttpPollingJob
和PollingJob
类中缺少默认构造函数原因是Scheduler无法创建他们的实例,
简单解决方案在以下类中添加以下代码
HttpPollingJob 类
public HttpPollingJob() {
}
PollingJob 类
public PollingJob() {
}
Bingo,将打印以下消息
Job fired!
Job fired!
Job fired!
如果您想重复触发,请在 PollingJob
中添加以下代码protected final Trigger getDefaultTrigger() {
TriggerBuilder<?> triggerBuilder = TriggerBuilder
.newTrigger()
.startNow()
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMilliseconds(DEF_FREQUENCY).repeatForever());
return triggerBuilder.build();
}
希望现在我会收到赏金:)
<强>奖金强>
好像你想要使用网址进行民意调查或做某事,使用国王JobDataMap
更新了 JobDriver
import java.util.ArrayList;
import java.util.List;
import org.quartz.JobBuilder;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
public class JobDriver {
private List<HttpPollingJob> jobs;
public JobDriver() {
HttpPollingJob job1 = new HttpPollingJob("job-1",
"http://www.example.com/1");
HttpPollingJob job2 = new HttpPollingJob("job-2",
"http://www.example.com/2");
HttpPollingJob job3 = new HttpPollingJob("job-3",
"http://www.example.com/3");
jobs = new ArrayList<HttpPollingJob>();
jobs.add(job1);
jobs.add(job2);
jobs.add(job3);
}
public static void main(String[] args) {
JobDriver driver = new JobDriver();
driver.startJobs();
}
private void startJobs() {
try {
// Obtain a basic SchedulerFactory and fire it up.
SchedulerFactory schedulerFactory = new org.quartz.impl.StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
// Define a job for every declared monitor.
JobBuilder jobBuilder = null;
for (HttpPollingJob job : jobs) {
Trigger trigger = job.getTrigger();
jobBuilder = JobBuilder.newJob(job.getClass());
jobBuilder.usingJobData("name", job.getName());
jobBuilder.usingJobData("url", job.getServerURL());
// Bind the current job to this trigger.
scheduler.scheduleJob(jobBuilder.build(), trigger);
// TODO: Shut the scheduler down politely?!?!
}
} catch (Throwable exc) {
// Force application to kick out.
throw new RuntimeException(exc);
}
}
}
更新 HttpPollingJob
import java.util.Map;
import org.quartz.JobExecutionContext;
public class HttpPollingJob extends PollingJob {
private String serverURL;
private org.slf4j.Logger logger =
org.slf4j.LoggerFactory.getLogger(HttpPollingJob.class);
public HttpPollingJob(final String nm, final String server) {
super(nm);
setServerURL(server);
}
public HttpPollingJob() {
}
public String getServerURL() {
return serverURL;
}
public void setServerURL(final String server) {
serverURL = server;
}
@Override
public final void poll(JobExecutionContext context) {
try {
Map dataMap = context.getJobDetail().getJobDataMap();
String nm = (String)dataMap.get("name");
String url = (String)dataMap.get("url");
// This is where we would use HttpClient to connect to a web server and poll it.
System.out.println("Job fired! name:"+nm+" url:"+url);
}
catch(Throwable thrown) {
logger.error(thrown.getMessage());
}
}
}
新输出
Job fired! name:job-1 url:http://www.example.com/1
Job fired! name:job-2 url:http://www.example.com/2
Job fired! name:job-3 url:http://www.example.com/3
答案 1 :(得分:4)
显然,你没有启动触发器。请参阅Quartz Tutorial或Javadocs:
// Trigger the job to run now, and then every 40 seconds
Trigger trigger = newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(40)
.repeatForever())
.build();
答案 2 :(得分:3)
它是你的构造函数 - JobBuilder
寻找no-args,因为它们没有被定义,所以它拒绝构建作业。添加空的无法工具,你就完全了。
答案 3 :(得分:0)
您是否可以尝试将类getDefaultTrigger
中方法PollingJob
的代码更改为以下内容:
protected final Trigger getDefaultTrigger() {
return TriggerBuilder.newTrigger()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMilliseconds(DEF_FREQUENCY))
.startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
.build();
}
答案 4 :(得分:0)
我觉得你创建触发器的方式有些问题。 请记住,您不能重复使用多个作业的触发器
尝试创建具有唯一标识和组的触发器,如下所示
触发everyHourTrigger = newTrigger()。withIdentity(“everyWeeklyTrigger”,“group1”) .startNow()。withSchedule(cronSchedule(“0 1 * * *?”))。build();