0

CommandQueueQuartz Job クラスから参照している Spring シングルトンがあります。ジョブがトリガーされると、CommandQueue に Command をエンキューすることになっています (Command を呼び出す"write()"と、Jackson を使用してシリアル化され、呼び出すと"Command.create(String)"コマンドが逆シリアル化されます)。

私が抱えている問題は、Job が Spring ではなく Quartz によってインスタンス化されているため@Autowire、Job で CommandQueue を作成したり、 への参照を取得したりできないことApplicationContextです。CommandQueue をジョブのコンストラクターに渡してから、ジョブの JobDataMap で CommandQueue をシリアル化することもできません。これは、CommandQueue を逆シリアル化すると、シングルトンを参照する代わりに新しい CommandQueue インスタンスが作成されるためです。

現在、Job インスタンスから 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);
        }
    }
}
4

1 に答える 1

0

私の間違い、質問はすでにここで答えられました春のクォーツの仕事に豆の参照を注入しますか?解決策は、SchedulerFactoryBeanを使用してから、そのApplicationContextSchedulerContextKeyプロパティを設定することです。

于 2013-01-02T17:58:47.193 に答える