如何以编程方式创建触发器对象?

发布于 2024-10-14 06:40:33 字数 2489 浏览 1 评论 0原文

我正在使用 Springquartz Scheduler,但我没有使用 XML 文件。我想以编程方式创建整个配置。

我编写了以下代码。

package com.eaportal.service.impl;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.quartz.JobDetail;
import org.springframework.scheduling.SchedulingException;
import org.springframework.scheduling.quartz.CronTriggerBean;
import org.springframework.scheduling.quartz.JobDetailBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import com.eaportal.service.intfc.AuctionWinnerService;

public class NormalAuctionWinnerServiceImpl1 implements AuctionWinnerService {

    @SuppressWarnings("deprecation")
    public void declareWinner(int auctionId, Map<String, Object> parameterMap) {
        System.out.println("INSIDE DECLARE WINNER METHOD.");
        /** STEP 1 : INSTANTIATE TASK CLASS **/
        NormalAuctionWinnerTask1 runMeTask = new NormalAuctionWinnerTask1();
        System.out.println("FINISHED STEP 1");

        /** STEP 2 : INSTANTIATE JOB DETAIL CLASS AND SET ITS PROPERTIES **/
        Map<String,Object> jobDataAsMap = new HashMap<String,Object>();
        jobDataAsMap.put("runMeTask",runMeTask);
        JobDetailBean jdb = new JobDetailBean();
        jdb.setJobClass(NormalAuctionWinnerTask1.class);
        jdb.setJobDataAsMap(jobDataAsMap);
        System.out.println("FINISHED STEP 2");

        /** STEP 3 : INSTANTIATE CRON TRIGGER AND SET ITS PROPERTIES **/
        CronTriggerBean ctb = new CronTriggerBean();
        Date d1 = new Date();
        Date d2 = new Date();
        d2.setMinutes(d1.getMinutes()+10);
        ctb.setStartTime(d1);
        ctb.setEndTime(d2);
        ctb.setJobDetail(jdb);

        try {
            ctb.setCronExpression("59 * * * * ? *");
        } catch (ParseException e) {
            e.printStackTrace();
        }

        /** STEP 4 : INSTANTIATE SCHEDULER FACTORY BEAN AND SET ITS PROPERTIES **/
        SchedulerFactoryBean sfb = new SchedulerFactoryBean();
        sfb.setJobDetails(new JobDetail[]{jdb});
        try {
            sfb.start();
        } catch (SchedulingException e) {
            e.printStackTrace();
        }
    }

}

该代码正在工作,只是触发器没有触发,因为我还没有设置它。

这里的问题是在 XML 配置中,我们有 SchedulerFactoryBean 的“triggers”属性,并且我们使用列表来配置触发器。

但我无法以编程方式设置相同的属性。 SchedulerFactoryBean中有一个setTriggers方法,它接受一个Trigger数组 但如何创建它是问题。

我在过去的 4 个小时里仍然没有成功的迹象。

有人可以帮我吗?

谢谢

I am using Spring quartz Scheduler but I am not using an XML file. I want to create the entire configuration programmatically.

I have written the following code.

package com.eaportal.service.impl;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.quartz.JobDetail;
import org.springframework.scheduling.SchedulingException;
import org.springframework.scheduling.quartz.CronTriggerBean;
import org.springframework.scheduling.quartz.JobDetailBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import com.eaportal.service.intfc.AuctionWinnerService;

public class NormalAuctionWinnerServiceImpl1 implements AuctionWinnerService {

    @SuppressWarnings("deprecation")
    public void declareWinner(int auctionId, Map<String, Object> parameterMap) {
        System.out.println("INSIDE DECLARE WINNER METHOD.");
        /** STEP 1 : INSTANTIATE TASK CLASS **/
        NormalAuctionWinnerTask1 runMeTask = new NormalAuctionWinnerTask1();
        System.out.println("FINISHED STEP 1");

        /** STEP 2 : INSTANTIATE JOB DETAIL CLASS AND SET ITS PROPERTIES **/
        Map<String,Object> jobDataAsMap = new HashMap<String,Object>();
        jobDataAsMap.put("runMeTask",runMeTask);
        JobDetailBean jdb = new JobDetailBean();
        jdb.setJobClass(NormalAuctionWinnerTask1.class);
        jdb.setJobDataAsMap(jobDataAsMap);
        System.out.println("FINISHED STEP 2");

        /** STEP 3 : INSTANTIATE CRON TRIGGER AND SET ITS PROPERTIES **/
        CronTriggerBean ctb = new CronTriggerBean();
        Date d1 = new Date();
        Date d2 = new Date();
        d2.setMinutes(d1.getMinutes()+10);
        ctb.setStartTime(d1);
        ctb.setEndTime(d2);
        ctb.setJobDetail(jdb);

        try {
            ctb.setCronExpression("59 * * * * ? *");
        } catch (ParseException e) {
            e.printStackTrace();
        }

        /** STEP 4 : INSTANTIATE SCHEDULER FACTORY BEAN AND SET ITS PROPERTIES **/
        SchedulerFactoryBean sfb = new SchedulerFactoryBean();
        sfb.setJobDetails(new JobDetail[]{jdb});
        try {
            sfb.start();
        } catch (SchedulingException e) {
            e.printStackTrace();
        }
    }

}

The code is working except the trigger doesn't fire coz I haven't set it.

Here the problem is in XML configuration we have 'triggers' property of schedulerFactoryBean and we use list to configure our triggers.

But I am not able to set the same property programmatically.
There is a setTriggers method in SchedulerFactoryBean that accepts an array of Trigger
but how to create it is the problem.

I am on it for the last 4 hrs still no sign of success.

Can someone help me here?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

何其悲哀 2024-10-21 06:40:33

我能够使用 Spring Scheduling Framework 成功地做到这一点。

我知道这是一篇非常古老的文章,但由于该主题的内容非常稀缺,因此将其放在这里应该是一个更好的主意。

第一篇文章代码中的主要问题是 afterPropertiesSet() 尚未在 JobDetail 对象以及 CronTrigger 上调用代码>对象。 afterProperties 函数在 cron 准备运行之前对输入的值进行一些处理。

另外,我使用了 MethodInvokingJobDetailFactoryBean 而不是常规的 jobDetail 对象,因为它为我在给定类中由 cron 调用的函数提供了更大的灵活性。

这是我的代码:

package test.spring;

import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.scheduling.SchedulingException;
import org.springframework.scheduling.quartz.CronTriggerBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import java.text.ParseException;

public class ProgrammaticCron {

    public static void callWorkFlow() {
        System.out.println("Abhishek Jain");
    }

    public static void main (String[] args) {
        try {
            GenericApplicationContext applicationContext = new GenericApplicationContext();

            MethodInvokingJobDetailFactoryBean jdfb = new MethodInvokingJobDetailFactoryBean();
            jdfb.setTargetClass(ProgrammaticCron.class);
            jdfb.setTargetMethod("callWorkFlow");
            jdfb.setName("Trial program");
            jdfb.afterPropertiesSet();
            JobDetail jd = (JobDetail)jdfb.getObject();

            CronTriggerBean ctb = new CronTriggerBean();
            ctb.setJobDetail(jd);
            ctb.setName("Daily cron");
            ctb.setJobName(jd.getName());
            try {
                ctb.setCronExpression("59 * * * * ? *");
            } catch (ParseException e) {
                e.printStackTrace();
            }

            ctb.afterPropertiesSet();

            SchedulerFactoryBean sfb = new SchedulerFactoryBean();
            sfb.setJobDetails(new JobDetail[]{(JobDetail)jdfb.getObject()});
            sfb.setTriggers(new Trigger[]{ctb});
            sfb.afterPropertiesSet();
            try {
                sfb.start();
            } catch (SchedulingException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

afterProperties() 很重要,可以从 SchedulerFactoryBeanafterProperties 实现来理解,如下所示

    //---------------------------------------------------------------------
// Implementation of InitializingBean interface
//---------------------------------------------------------------------

public void afterPropertiesSet() throws Exception {
    if (this.dataSource == null && this.nonTransactionalDataSource != null) {
        this.dataSource = this.nonTransactionalDataSource;
    }

    if (this.applicationContext != null && this.resourceLoader == null) {
        this.resourceLoader = this.applicationContext;
    }

    // Create SchedulerFactory instance.
    SchedulerFactory schedulerFactory = (SchedulerFactory)
            BeanUtils.instantiateClass(this.schedulerFactoryClass);

    initSchedulerFactory(schedulerFactory);

    if (this.resourceLoader != null) {
        // Make given ResourceLoader available for SchedulerFactory configuration.
        configTimeResourceLoaderHolder.set(this.resourceLoader);
    }
    if (this.taskExecutor != null) {
        // Make given TaskExecutor available for SchedulerFactory configuration.
        configTimeTaskExecutorHolder.set(this.taskExecutor);
    }
    if (this.dataSource != null) {
        // Make given DataSource available for SchedulerFactory configuration.
        configTimeDataSourceHolder.set(this.dataSource);
    }
    if (this.nonTransactionalDataSource != null) {
        // Make given non-transactional DataSource available for SchedulerFactory configuration.
        configTimeNonTransactionalDataSourceHolder.set(this.nonTransactionalDataSource);
    }


    // Get Scheduler instance from SchedulerFactory.
    try {
        this.scheduler = createScheduler(schedulerFactory, this.schedulerName);
        populateSchedulerContext();

        if (!this.jobFactorySet && !(this.scheduler instanceof RemoteScheduler)) {
            // Use AdaptableJobFactory as default for a local Scheduler, unless when
            // explicitly given a null value through the "jobFactory" bean property.
            this.jobFactory = new AdaptableJobFactory();
        }
        if (this.jobFactory != null) {
            if (this.jobFactory instanceof SchedulerContextAware) {
                ((SchedulerContextAware) this.jobFactory).setSchedulerContext(this.scheduler.getContext());
            }
            this.scheduler.setJobFactory(this.jobFactory);
        }
    }

    finally {
        if (this.resourceLoader != null) {
            configTimeResourceLoaderHolder.remove();
        }
        if (this.taskExecutor != null) {
            configTimeTaskExecutorHolder.remove();
        }
        if (this.dataSource != null) {
            configTimeDataSourceHolder.remove();
        }
        if (this.nonTransactionalDataSource != null) {
            configTimeNonTransactionalDataSourceHolder.remove();
        }
    }

    registerListeners();
    registerJobsAndTriggers();
        }

:请注意,所有此类任务(例如获取调度程序和使用触发器注册作业)都是作为此函数的一部分完成的。

I was able to do this with Spring Scheduling Framework successfully.

I understand this is a very old post but as the content on this topic is pretty scarce, it should be a better idea to put it here.

The major problem in the code for the first post is that the afterPropertiesSet() hasn't been invoked on both the JobDetail object as well as the CronTrigger object. The afterProperties function does some processing on the entered values before the cron is ready to be run.

Also, I have used the MethodInvokingJobDetailFactoryBean instead of the regular jobDetail object as it gives me more flexibility on the function to be called by the cron in the given class.

Here is my code:

package test.spring;

import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.scheduling.SchedulingException;
import org.springframework.scheduling.quartz.CronTriggerBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import java.text.ParseException;

public class ProgrammaticCron {

    public static void callWorkFlow() {
        System.out.println("Abhishek Jain");
    }

    public static void main (String[] args) {
        try {
            GenericApplicationContext applicationContext = new GenericApplicationContext();

            MethodInvokingJobDetailFactoryBean jdfb = new MethodInvokingJobDetailFactoryBean();
            jdfb.setTargetClass(ProgrammaticCron.class);
            jdfb.setTargetMethod("callWorkFlow");
            jdfb.setName("Trial program");
            jdfb.afterPropertiesSet();
            JobDetail jd = (JobDetail)jdfb.getObject();

            CronTriggerBean ctb = new CronTriggerBean();
            ctb.setJobDetail(jd);
            ctb.setName("Daily cron");
            ctb.setJobName(jd.getName());
            try {
                ctb.setCronExpression("59 * * * * ? *");
            } catch (ParseException e) {
                e.printStackTrace();
            }

            ctb.afterPropertiesSet();

            SchedulerFactoryBean sfb = new SchedulerFactoryBean();
            sfb.setJobDetails(new JobDetail[]{(JobDetail)jdfb.getObject()});
            sfb.setTriggers(new Trigger[]{ctb});
            sfb.afterPropertiesSet();
            try {
                sfb.start();
            } catch (SchedulingException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

afterProperties() is important and it can be understood from the afterProperties implementation of SchedulerFactoryBean which is as follows:

    //---------------------------------------------------------------------
// Implementation of InitializingBean interface
//---------------------------------------------------------------------

public void afterPropertiesSet() throws Exception {
    if (this.dataSource == null && this.nonTransactionalDataSource != null) {
        this.dataSource = this.nonTransactionalDataSource;
    }

    if (this.applicationContext != null && this.resourceLoader == null) {
        this.resourceLoader = this.applicationContext;
    }

    // Create SchedulerFactory instance.
    SchedulerFactory schedulerFactory = (SchedulerFactory)
            BeanUtils.instantiateClass(this.schedulerFactoryClass);

    initSchedulerFactory(schedulerFactory);

    if (this.resourceLoader != null) {
        // Make given ResourceLoader available for SchedulerFactory configuration.
        configTimeResourceLoaderHolder.set(this.resourceLoader);
    }
    if (this.taskExecutor != null) {
        // Make given TaskExecutor available for SchedulerFactory configuration.
        configTimeTaskExecutorHolder.set(this.taskExecutor);
    }
    if (this.dataSource != null) {
        // Make given DataSource available for SchedulerFactory configuration.
        configTimeDataSourceHolder.set(this.dataSource);
    }
    if (this.nonTransactionalDataSource != null) {
        // Make given non-transactional DataSource available for SchedulerFactory configuration.
        configTimeNonTransactionalDataSourceHolder.set(this.nonTransactionalDataSource);
    }


    // Get Scheduler instance from SchedulerFactory.
    try {
        this.scheduler = createScheduler(schedulerFactory, this.schedulerName);
        populateSchedulerContext();

        if (!this.jobFactorySet && !(this.scheduler instanceof RemoteScheduler)) {
            // Use AdaptableJobFactory as default for a local Scheduler, unless when
            // explicitly given a null value through the "jobFactory" bean property.
            this.jobFactory = new AdaptableJobFactory();
        }
        if (this.jobFactory != null) {
            if (this.jobFactory instanceof SchedulerContextAware) {
                ((SchedulerContextAware) this.jobFactory).setSchedulerContext(this.scheduler.getContext());
            }
            this.scheduler.setJobFactory(this.jobFactory);
        }
    }

    finally {
        if (this.resourceLoader != null) {
            configTimeResourceLoaderHolder.remove();
        }
        if (this.taskExecutor != null) {
            configTimeTaskExecutorHolder.remove();
        }
        if (this.dataSource != null) {
            configTimeDataSourceHolder.remove();
        }
        if (this.nonTransactionalDataSource != null) {
            configTimeNonTransactionalDataSourceHolder.remove();
        }
    }

    registerListeners();
    registerJobsAndTriggers();
        }

As you may notice, all such tasks as getting the scheduler and registering the job with the triggers is done as a part of this function.

怪我太投入 2024-10-21 06:40:33

主要问题应该是,您需要安排作业:

scheduler.scheduleJob(jobDetail, trigger);

我不知道 Spring Quarz Beans 的情况如何,但正常的 Quarz 作业和触发器必须有一个名称和一个组!您可能需要启动调度程序: scheduler.start();

我对您的代码进行了一些修改,使其无需 spring 即可工作,并且全部省略了不需要的内容,以演示它是如何实现的工作原理:

封装测试;

import java.text.ParseException;
import java.util.Date;

import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;


public class Demo {

    public static class TestJob implements Job{
        @Override
        public void execute(JobExecutionContext arg0) throws JobExecutionException {
            System.out.println("execute");          
        }
    }

    public static void declareWinner() throws SchedulerException, ParseException {

        JobDetail jobDetail = new JobDetail("job","group",Demo.TestJob.class);

        CronTrigger trigger = new CronTrigger("trigger","group");

        trigger.setStartTime(new Date());
        trigger.setEndTime(new Date(new Date().getTime() + 10 * 60 * 1000));
        trigger.setCronExpression("* * * * * ? *");     

        /** STEP 4 : INSTANTIATE SCHEDULER FACTORY BEAN AND SET ITS PROPERTIES **/
        SchedulerFactory sfb = new StdSchedulerFactory();
        Scheduler scheduler = sfb.getScheduler();       

        scheduler.scheduleJob(jobDetail, trigger);      

        scheduler.start();                  
    }

    public static void main (String[] args) throws SchedulerException, Exception {
        declareWinner();
        Thread.sleep(10000);
    }

}

The main problem should be, that you need to schedule the job:

scheduler.scheduleJob(jobDetail, trigger);

And I do not know how it is for Spring Quarz Beans, but normal Quarz Jobs and Trigger must have a name and a group! And may you need to start the scheduler: scheduler.start();

I have modified your code a bit that it works without spring, and all leave out the stuff that is not needed, to demonstrate how it works:

package test;

import java.text.ParseException;
import java.util.Date;

import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;


public class Demo {

    public static class TestJob implements Job{
        @Override
        public void execute(JobExecutionContext arg0) throws JobExecutionException {
            System.out.println("execute");          
        }
    }

    public static void declareWinner() throws SchedulerException, ParseException {

        JobDetail jobDetail = new JobDetail("job","group",Demo.TestJob.class);

        CronTrigger trigger = new CronTrigger("trigger","group");

        trigger.setStartTime(new Date());
        trigger.setEndTime(new Date(new Date().getTime() + 10 * 60 * 1000));
        trigger.setCronExpression("* * * * * ? *");     

        /** STEP 4 : INSTANTIATE SCHEDULER FACTORY BEAN AND SET ITS PROPERTIES **/
        SchedulerFactory sfb = new StdSchedulerFactory();
        Scheduler scheduler = sfb.getScheduler();       

        scheduler.scheduleJob(jobDetail, trigger);      

        scheduler.start();                  
    }

    public static void main (String[] args) throws SchedulerException, Exception {
        declareWinner();
        Thread.sleep(10000);
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文