如何使用Spring(和Quartz)动态启动预定作业?

时间:2016-03-28 17:09:25

标签: java spring quartz-scheduler

我在this教程之后用Spring安排工作。

在教程中,调度由以下代码启动:

public static void main(String args[]){
    AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml");
}

我不想使用main,而是希望使用可以在我的应用程序中的任何位置调用的方法来启动作业,例如:

public void startJobs() {
    // what should this method do to start the jobs?
}

以下工作可以吗?

public void startJobs() {
    AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml");
}

这被视为良好做法吗?

基本上我想要实现的是能够随时启动作业(每当我调用startJobs()方法时),而不是在main方法启动时。

我该怎么做?

2 个答案:

答案 0 :(得分:3)

您是否完成了使用石英和弹簧的计划。如果是,它运行正常吗?您共享的示例链接属于"任务命名空间"

Quartz使用Trigger,Job和JobDetail对象来实现各种作业的调度。有关Quartz背后的基本概念,请查看

http://quartz-scheduler.org/documentation/quartz-2.2.x/quick-start

要将其与Spring集成,请同时查看

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-quartz-jobdetail

Spring和quartz的XML配置。

<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository" />
</bean>
    <bean
        class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
        <property name="jobRegistry" ref="jobRegistry" />
    </bean>

    <bean id="jobRegistry"
        class="org.springframework.batch.core.configuration.support.MapJobRegistry" />

    <bean name="csvLoaderJobDetail"
        class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.example.CSVloader.ScheduledJob" />
        <property name="jobDataMap">
            <map>
                <entry key="csvData" value="value1" />
                <entry key="date" value="25/09/2015" />
                <entry key="csvId" value="1" />
                <entry key="jobName" value="csvLoadJob" />
                <entry key="jobLocator" value-ref="jobRegistry" />
                <entry key="jobLauncher" value-ref="jobLauncher" />
            </map>
        </property>
        <property name="durability" value="true" />
    </bean>

    <bean id="csvLoaderTrigger"
        class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="csvLoaderJobDetail" />
        <property name="cronExpression" value="0 0 12 * * ?" />
    </bean>

    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="jobDetails">
            <list>
                <ref bean="csvLoaderJobDetail" />
            </list>
        </property>
        <property name="triggers">
            <list>
                <ref bean="csvLoaderTrigger" />
            </list>
        </property>
        <property name="quartzProperties">
            <props>
                <prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>
            </props>
        </property>
    </bean>

要手动触发作业,需要在spring bean中注入SchedulerFactoryBean。首先,您需要获取在石英调度程序中创建的所有作业,然后您可以使用每个作业的作业键和作业组手动触发任何作业。

    @Autowired
    private SchedulerFactoryBean schedulerFactory;

    org.quartz.Scheduler scheduler = schedulerFactory.getScheduler();

    // loop jobs by group
    for (String groupName : scheduler.getJobGroupNames()) {

           // get jobkey
           for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher
    .jobGroupEquals(groupName))) {

               String jobName = jobKey.getName();
               String jobGroup = jobKey.getGroup();

               scheduler.triggerJob(jobName,  jobGroup);
            }
    }

现在您可以创建一个Object列表,其中包含jobName和jobGroup以手动触发任何作业。

答案 1 :(得分:1)

更好更简单的方法,使用@Scheduled注释。

方法1)在@Scheduled注释中使用固定延迟属性的任务调度

 @Scheduled(fixedDelay = 5000)

方法2)在@Scheduled注释中使用cron表达式的任务调度

 @Scheduled(cron="*/5 * * * * ?")

方法3)使用属性文件中的cron表达式进行任务调度

@Scheduled(cron = "${cron.expression}")

您可以获得完整的示例here