2

我环顾四周寻找这个答案,但我一直无法找到一个好的答案。我想创建一个基于 Quartz 的系统,允许人们安排自己的任务。我将使用一个伪示例。

  1. 假设我的 Quartz 程序的主要方法称为quartz.java。
  2. 然后我有一个名为sweep.java 的文件,它实现了Quartz“作业”接口。

所以在我的quartz.java 中,我安排我的sweep.java 每小时运行一次。我运行quartz.java,它工作正常。伟大的; 但是,现在我想向石英调度程序添加一个dust.java;但是,由于这是一个生产服务,我不想停止我的quartz.java 文件,添加我的dust.java,然后重新编译并再次运行quartz.java。这种停机时间是不可接受的。

有人对我如何做到这一点有任何想法吗?这似乎是不可能的,因为你怎么能在不重新编译、链接等的情况下将另一个 java 文件输入到程序中呢?

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

4

2 回答 2

0

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

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

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

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

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

public interface MyDynamicJob
{
    public void executeThisAsPartOfJob();
}

创建 Job 方法的实例。

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

现在在您的主调度程序引擎中,使用观察者模式来动态存储/启动作业。就像是,

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");
    }

}    
于 2013-06-04T03:38:58.007 回答
0

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

以下是示例代码的链接:

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

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

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

于 2013-06-03T14:57:16.347 回答