简体   繁体   中英

How to set up simple Spring scheduled task

The following is what I suppose to be the relevant documentation from the Spring site:

34.2.2 Using a TaskExecutor Spring's TaskExecutor implementations are used as simple JavaBeans. In the example below, we define a bean that uses the ThreadPoolTaskExecutor to asynchronously print out a set of messages.

import org.springframework.core.task.TaskExecutor;

public class TaskExecutorExample {

  private class MessagePrinterTask implements Runnable {

      private String message;

      public MessagePrinterTask(String message) {
          this.message = message;
      }

      public void run() {
          System.out.println(message);
      }

  }

  private TaskExecutor taskExecutor;

  public TaskExecutorExample(TaskExecutor taskExecutor) {
      this.taskExecutor = taskExecutor;
  }

  public void printMessages() {
      for(int i = 0; i < 25; i++) {
          taskExecutor.execute(new MessagePrinterTask("Message" + i));
      }
  }

}

As you can see, rather than retrieving a thread from the pool and executing yourself, you add your Runnable to the queue and the TaskExecutor uses its internal rules to decide when the task gets executed.

To configure the rules that the TaskExecutor will use, simple bean properties have been exposed.

<bean id="taskExecutor"     class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
  <property name="corePoolSize" value="5" />
  <property name="maxPoolSize" value="10" />
  <property name="queueCapacity" value="25" />
</bean>

<bean id="taskExecutorExample" class="TaskExecutorExample">
  <constructor-arg ref="taskExecutor" />
</bean>

I'm going to have to deal with a Trigger eventually, because I want to do something every N hours/minutes, but for the moment I'm still staring at this example. How does the method printMessages() get executed? I don't see anywhere in the configuration or the code that mentions it.

Incidentally, this is the entire subsection from the documentation: "34.2.2 Using a TaskExecutor"

There's nothing fancy about the executors and spring. In the example you've posted you've got a bean which implements Runnable with the run method. In there you should define what you want to be run by the executor. In your case it is

 public void run() {
      System.out.println(message);
  }

And then you've got an executor which will execute this task via

taskExecutor.execute(new MessagePrinterTask("Message" + i));

If you are wondering where you need to call this line (invoke the method) then it really depends on your app and what you r trying to do. In your example, whenever you call printMessages() your task will be executed 25 times in a loop.

Now you've mentioned about the Trigger and how to set it up. My advice is the following. Create simple pojos for all of the tasks you want to be executed which implement an interface like so

public interface Poller extends Runnable
{
  Trigger getTrigger();
}

In all of these classes implement the run task (what to be executed) + the getTrigger method defining your desired trigger for the task and then in your config class you need to register them like

@Configuration
@EnableScheduling
public class Config implements SchedulingConfigurer
{
  //autowire all pollers
  @Autowired
  private List<Poller> pollers;

  @Bean(destroyMethod = "shutdown")
  public Executor taskExecutor() 
  {
    return Executors.newScheduledThreadPool(25);
  }

  @Override
  public void configureTasks(ScheduledTaskRegistrar taskRegistrar)
  {
    taskRegistrar.setScheduler(taskExecutor());

    for(Poller poller : pollers)
    {
      //register the task and trigger for it to be executed
      taskRegistrar.addTriggerTask(poller, poller.getTrigger());
    }
  }  

}

This should automatically start executing all of your tasks with the desired triggers. I hope it makes sense.

The following configures a method in a bean to run according to a CRON-string schedule, using XML configuration.

We need:

  1. a task bean that specifies a class which is instantiated and run,
  2. a trigger bean that specifies how often to run and the task bean from step 1,
  3. a quartz bean to fire the trigger from step 2 on the trigger's schedule.

Here are configurations like mine, put in 'applicationContext.xml':

In the 'applicationContext.xml' for the application, I put the following beans:

<!-- this task is one that runs periodically, with the period specified elsewhere -->
<!-- it refreshes data that doesn't change often -->
<bean id="myRefreshTask" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass" value="com.mycompany.myRefreshTask"/>
</bean>

<!-- this trigger specifies a task and a cron string for a period on which that task runs -->
<bean id="myRefreshTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="myRefreshTask"/>
    <property name="cronExpression" value="0 0/1 * 1/1 * ? *"/> <!-- for example testing, every minute -->
    <!--<property name="cronExpression" value="0 30 6 1/1 * ? *"/>--> <!-- for production, every day 6:30am -->
</bean>

<!-- this is a list of triggers for quartz to fire at their specified intervals -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="myRefreshTrigger"/>
        </list>
    </property>
</bean>

Then the class MyRefreshTask was written as follows:

package mycompany;
public class MyRefreshTask extends QuartzJobBean {
    @Override
    public void executeInternal(JobExecutionContext context) throws JobExecutionException {
        log.info("MyRefreshTask executing" );
    }
}

This produced a line in (one of the) log file(s) every minute. I'd love to know how to predict which log file will end up containing the System.out output from different parts of the application for Tomcat, but that's for another day.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM