30

我想知道如何在 Quartz 中从外部传递实例变量?

下面是我想写的伪代码。如何将 externalInstance 传递给此作业?

public class SimpleJob implements Job {
        @Override
        public void execute(JobExecutionContext context)
                throws JobExecutionException {

            float avg = externalInstance.calculateAvg();
        }
}
4

6 回答 6

61

您可以将您的实例放在 schedulerContext 中。当您要安排作业时,在此之前您可以执行以下操作:

getScheduler().getContext().put("externalInstance", externalInstance);

您的工作类别如下所示:

public class SimpleJob implements Job {
    @Override
    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        SchedulerContext schedulerContext = null;
        try {
            schedulerContext = context.getScheduler().getContext();
        } catch (SchedulerException e1) {
            e1.printStackTrace();
        }
        ExternalInstance externalInstance =
            (ExternalInstance) schedulerContext.get("externalInstance");

        float avg = externalInstance.calculateAvg();
    }
}

如果您使用的是 Spring,您实际上可以使用 Spring 的支持来注入整个 applicationContext,就像在链接中回答的那样

于 2012-10-08T13:23:25.107 回答
10

在使用触发器调度作业时,您将定义JobDataMap添加到JobDetail. 该 JobDetail 对象将出现在JobExecutionContext传递给execute()您的Job. 因此,您应该想办法通过JobDataMap. HTH。

于 2012-10-08T07:37:44.153 回答
4

将对象添加到 JobDataMap:

JobDetail job = JobBuilder.newJob(MyJobClass.class)
                          .withIdentity("MyIdentity",
                                        "MyGroup")
                          .build();
job.getJobDataMap()
   .put("MyObject",
        myObject);

从 JobDataMap 访问数据:

var myObject = (MyObjectClass) context.getJobDetail()
                                      .getJobDataMap()
                                      .get("carrier");
于 2019-10-07T13:49:04.290 回答
2

通过创建一个界面并在其中HashMap放置所需信息来解决此问题。

在你的 QuartzJob类中实现这个接口,这个信息将是可访问的。

IFace

Map<JobKey,Object> map = new HashMap<>();

Job

map.get(context.getJobDetail().getKey()) =>  will give you Object
于 2016-10-13T10:38:26.243 回答
2

Quartz 有一种使用 setter 从 JobDataMap grep 参数的简单方法

我正在使用 Quartz 2.3,我只是使用 setter 来获取传递的实例对象

例如我创建了这个类

public class Data implements Serializable {
    @JsonProperty("text")
    private String text;

    @JsonCreator
    public Data(@JsonProperty("b") String text) {this.text = text;}

    public String getText() {return text;}
}

然后我创建了这个类的一个实例并将它放在 JobDataMap 中

JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("data", new Data(1, "One!"));
JobDetail job = newJob(HelloJob.class)
                .withIdentity("myJob", "group")
                .withDescription("bla bla bla")
                .usingJobData(jobDataMap) // <!!!
                .build();

我的工作课看起来像这样

public class HelloJob implements Job {
    Data data;

    public HelloJob() {}

    public void execute(JobExecutionContext context)
            throws JobExecutionException
    {
        String text = data.getText();
        System.out.println(text);
    }

    public void setData(Data data) {this.data = data;}
}
  • 注意:字段和setter必须匹配key

One!此代码将在您安排作业时打印。

就是这样,干净高效

于 2019-11-11T13:00:02.077 回答
0

这是 的责任JobFactory。默认PropertySettingJobFactory实现将根据在 schdeuler 上下文、触发器和作业详细信息中找到的属性调用任何 bean-setter 方法。因此,只要您实施了适当的setContext()setter 方法,您就应该能够执行以下任何操作:

scheduler.getContext().put("context", context);

或者

Trigger trigger = TriggerBuilder.newTrigger()
  ...
  .usingJobData("context", context)
  .build()

或者

JobDetail job = JobBuilder.newJob(SimpleJob.class)
  ...
  .usingJobData("context", context)
  .build()

或者,如果这还不够,您可以提供自己的JobFactory类来实例化 Job 对象,但您可以随意。

于 2016-08-31T13:23:18.597 回答