How to start scheduled jobs dynamically with Spring (and Quartz)?

二次信任 提交于 2020-01-14 12:38:11

问题


I'm following this tutorial to schedule jobs with Spring.

In the tutorial scheduling is started by the following code:

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

Instead of using main, i'd like to start jobs with a method that can be called from anywhere in my application, for example:

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

Can the following work?

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

Is this considered good practice?

Basically what i want to achieve is to be able to start the jobs whenever i want (whenever i call the startJobs() method), not on startup in the main method.

How can i do this?


回答1:


Have you done with scheduling using quartz and spring. If yes, is it running fine? The example link you shared belongs to "The Task Namespace"

Quartz uses Trigger, Job and JobDetail objects to realize scheduling of all kinds of jobs. For the basic concepts behind Quartz, have a look at

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

To integrate it with Spring, Please have a look at this also

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

XML Configuration of Spring and quartz.

<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>

To fire the job manually, you need to inject SchedulerFactoryBean in your spring bean. First you need to get all the jobs created in quartz scheduler, then you can trigger any job manually by using Job Key and Job group of each job.

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

Now you can create a list of Object, which contain jobName and jobGroup to trigger any job manually.




回答2:


A better and easy way , use @Scheduled annotation.

Method 1) Task scheduling using fixed delay attribute in @Scheduled annotation

 @Scheduled(fixedDelay = 5000)

Method 2) Task scheduling using cron expression in @Scheduled annotation

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

Method 3) Task scheduling using cron expression from properties file

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

You can get complete example here



来源:https://stackoverflow.com/questions/36267127/how-to-start-scheduled-jobs-dynamically-with-spring-and-quartz

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!