如何以编程方式创建触发器对象? [英] How to create Trigger Object Programmatically?

查看:178
本文介绍了如何以编程方式创建触发器对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我写了以下代码.

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.

这里的问题是在XML配置中,我们具有schedulerFactoryBean的"triggers"属性,并使用list来配置触发器.

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

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

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.

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

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

有人可以在这里帮助我吗?

Can someone help me here?

谢谢

推荐答案

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

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.

第一篇文章代码中的主要问题是afterPropertiesSet()对象和CronTrigger对象均未调用afterPropertiesSet(). afterProperties函数在准备好运行cron之前会对输入的值进行一些处理.

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.

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

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.

这是我的代码:

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实现中理解,该实现如下:

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.

这篇关于如何以编程方式创建触发器对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆