将Spring单例与静态Quartz作业类集成
我有一个名为将Spring单例与静态Quartz作业类集成,spring,serialization,quartz-scheduler,Spring,Serialization,Quartz Scheduler,我有一个名为CommandQueue的Spring单例,我从Quartz作业类中引用它。当作业触发时,它应该将命令排入CommandQueue(对命令调用“write()”,使用Jackson将其序列化,调用“Command.create(String)”将命令反序列化) 我遇到的问题是,作业是由Quartz而不是Spring实例化的,因此我无法在作业中使用CommandQueue,也无法获得对ApplicationContext的引用。我也不能将CommandQueue传递给作业的构造函数,然
CommandQueue
的Spring单例,我从Quartz作业类中引用它。当作业触发时,它应该将命令排入CommandQueue(对命令调用“write()”
,使用Jackson将其序列化,调用“Command.create(String)”
将命令反序列化)
我遇到的问题是,作业是由Quartz而不是Spring实例化的,因此我无法在作业中使用CommandQueue,也无法获得对ApplicationContext
的引用。我也不能将CommandQueue传递给作业的构造函数,然后在作业的JobDataMap中序列化CommandQueue,因为当我反序列化CommandQueue时,我将创建一个新的CommandQueue实例,而不是引用singleton
目前,我正在使用一种变通方法,其中静态引用作业实例中的CommandQueue单例,但我想知道是否有一种方法可以在不诉诸静态引用的情况下完成同样的事情
public abstract class CommandQueue {
protected static CommandQueue queue;
public static CommandQueue queue() { return queue; }
protected CommandQueue() {}
}
@Service("CommandQueue")
@Scope(value = "singleton")
@Profile({"test"})
public class TestQueue extends CommandQueue {
public TestQueue() { CommandQueue.queue = this; }
}
@Service("CommandQueue")
@Scope(value = "singleton")
@Profile({"production"})
public class ProductionQueue extends CommandQueue {
public ProductionQueue() { CommandQueue.queue = this; }
}
@Service
@Scope(value = "singleton")
public class CommandScheduler {
private final org.quartz.Scheduler scheduler;
public CommandScheduler() {
scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
}
public JobKey scheduleRecurringSeconds(final Command command, final int seconds) {
JobDetail job = JobBuilder.newJob(CommandJob.class)
.withIdentity(command.getId()).build();
job.getJobDataMap().put("command", command.write());
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(command.getId()).startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(seconds).repeatForever())
.build();
scheduler.scheduleJob(job, trigger);
}
@DisallowConcurrentExecution
public static class CommandJob implements Job {
public void execute(JobExecutionContext context) {
String str = context.getJobDetail().getJobDataMap().get("command");
Command command = Command.create(str);
CommandQueue.queue().enqueue(command);
}
}
}
我的错误,这里已经回答了这个问题。解决方案是使用SchedulerFactoryBean,然后设置其ApplicationContextSchedulerContextKey属性,这实际上不是解决这个问题的最理想的方法。看看这个问题,看看如何在Quartz作业上实现类似Spring的依赖注入,而不是被迫从ApplicationContext手动检索bean