即时添加Quartz源Java文件

时间:2013-06-03 14:41:35

标签: java quartz-scheduler

我已经四处寻找这个答案,但我找不到一个好的答案。我想创建一个基于Quartz的系统,允许人们安排自己的任务。我将使用一个伪示例。

  1. 让我说我的Quartz程序的主要方法叫做quartz.java。
  2. 然后我有一个名为sweep.java的文件,它实现了Quartz" job"接口。
  3. 所以在我的quartz.java中,我安排我的sweep.java每小时运行一次。我运行quartz.java,它工作正常。大;但是,现在我想在quartz调度程序中添加一个dust.java;但是,由于这是一个生产服务,我不想要停止我的quartz.java文件,添加我的dust.java,并重新编译并再次运行quartz.java。这种停机时间是不可接受的。

    有没有人对如何做到这一点有任何想法?这似乎是不可能的,因为你怎么能在没有重新编译,链接等的情况下将另一个java文件提供给程序。

    我希望这个例子很清楚。如果我需要澄清它的任何部分,请告诉我。

2 个答案:

答案 0 :(得分:0)

部分答案:可以以编程方式编译,然后实例化一个类。

以下是示例代码的链接:

在第三个源文件中抓取提取的类(请参阅方法getGeneratedClass,该方法返回Class<?>个对象)。

HOWEVER :请记住,这样做有潜在危险。如果您不小心,可能会非常严重的一个问题是,当您动态实例化一个类时,执行其静态初始化块。这些可能会对您的应用程序造成严重破坏。因此,此外,您还必须创建适当的SecurityContext

在上面的代码中,我实际上只获取Class<?>对象并且从不以任何方式实例化它,因此不执行任何代码。但是您的使用场景非常不同。

答案 1 :(得分:0)

我没有尝试过这些,但值得一试。

1)考虑使用Quartz camel endpoint。 如果我的理解是正确的,Apache Camel可以让你动态创建骆驼路线。 它只需要将camel-context.xml部署到容器中,同时考虑到所需的类已经在容器的类路径上可用。

2)Quartz允许您以声明方式创建作业,即使用作业和触发器的xml配置。 您可以找到更多信息here

3)现在这需要一些努力; - )

创建一个接口,该接口具有您将作为作业的一部分执行的方法。让我们说这将有一个名为

的方法
public interface MyDynamicJob
{
    public void executeThisAsPartOfJob();
}

创建Job方法的实例。

public EmailJob implements MyDynamicJob
{
    @Override
    public void executeThisAsPartOfJob()
    {
        System.out.println("Sending Email");
    }
}

现在,在主调度程序引擎中,使用Observer模式动态存储/启动作业。 像,

HashMap jobs=new HashMap<String,MyDynamicJob>();

// call this method to add the job dynamically.
// If you add a job after the scheduler engine started , find a way here how to     reiterate over this map without shutting down the scheduler :-).
public void addJob(String someJobName,MyDynamicJob job)
{
    jobs.add(someJobName,job);
}

public void initiateScheduler()
{
    // Iterate over the jobs map to get all registered jobs. Create
    // Create JobDetail instances dynamically for each job Entry. add your custom job     class as a part of job data map.

        Job jd1=JobBuilder.newJob(GenericJob.class)
                .withIdentity("FirstJob", "First Group").build();   

        Map jobDataMap=jd1.getJobDataMap();
        jobDataMap.put("dynamicjob", jobs.get("dynamicjob1"));


}

public class GenericJob implements Job {

    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println("Executing job");

        Map jdm=arg0.getJobDetail().getJobDataMap();
        MyDynamicJob mdj=jdm.get("dynamicjob");
        // Now execute your custom job method here.
        mdj.executeThisAsPartOfJob();
        System.out.println("Job Execution complete");
    }

}