2016-08-31 2 views
1

Ниже то, что я полагаю, что соответствующая документация с сайта Spring:Как создать простой Spring запланированное задание

34.2.2 Использование реализаций TaskExecutor TaskExecutor Spring, используются в качестве простых JavaBeans. В приведенном ниже примере мы определяем компонент, который использует метод ThreadPoolTaskExecutor для асинхронной печати набора сообщений.

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

} 

Как вы можете видеть, вместо извлечения нити из пула и выполнения себя, вы добавить свой Runnable в очередь и TaskExecutor использует свои внутренние правила, чтобы решить, когда задача запускается на выполнение.

Чтобы настроить правила, используемые TaskExecutor, были открыты простые свойства bean-компонента.

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

Я буду иметь дело с триггером в конечном счете, потому что я хочу сделать что-то каждый N часов/минут, но на данный момент я все еще смотрел на этот пример. Как выполняется метод printMessages()? Я не вижу нигде в конфигурации или код, который упоминает об этом.

Кстати, это весь подраздел из документации: «34.2.2 Использование TaskExecutor»

+0

Вы хотите знать, как Spring вызывает метод или как вы можете вызвать метод в своем приложении? – george

+0

@george как настроить - как Spring вызывает это было бы интересно, но, вероятно, не нужно. Думал, что название послужит указанием на то, что я хотел, но вижу, что я задал вопрос в замешательстве в теле. – arcy

ответ

0

Там нет ничего фантазии об исполнителях и весной. В приведенном выше примере у вас есть компонент, который реализует Runnable с помощью метода run. Там вы должны определить, что вы хотите запустить исполнителем. В вашем случае это

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

И тогда у вас есть исполнитель, который будет выполнять эту задачу с помощью

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

Если вы задаетесь вопросом, где вам нужно вызвать эту строку (вызывается метод), то это действительно зависит от вашего приложения и того, что вы пытаетесь сделать. В вашем примере, когда вы вызываете printMessages(), ваша задача будет выполняться 25 раз в цикле.

Теперь вы упомянули о триггере и как его настроить. Мой совет таков. Создание простых объектов POJO для всех задач, которые вы хотите быть выполнены, которые реализуют интерфейс, как так

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

В каждом из этих классов реализовать поставленную задачу выполнения (что будет выполняться) + метод getTrigger определения нужного триггера для задача, а затем в своем классе конфигурации вы должны зарегистрировать их как

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

} 

это должно автоматически начать выполнение всех задач с желаемыми триггеров. Надеюсь, это имеет смысл.

+0

Ну, у этого есть больше информации, но я все еще немного смущен. Вы дали мне что-то, что включает в себя несколько «опылителей» и пул потоков, ни один из которых мне не нужен в данный момент. Как насчет этого: как я понял, и вы подтвердили, исходный пример имеет метод 'printMessages', который выведет 25 сообщений в System.out. Как я планирую, чтобы это выполнялось один раз каждые 24 часа? Мой первоначальный вопрос был на самом деле, как этот метод когда-либо выполняется, так как в документации, которую я цитирую, не упоминается ни в какой конфигурации, которую я мог бы сказать. – arcy

+0

то, что я вам дал, содержит ответ. С помощью триггера вы можете определить период времени для каждой задачи. Если вы хотите сохранить его простым и не возиться с taskExecutors, триггерами и т. Д., То вы можете просто аннотировать метод с помощью @Scheduled и передать ему задание cron за 24 часа. См. Здесь дополнительную информацию. http://howtodoinjava.com/spring/spring-core/4-ways-to-schedule-tasks-in-spring-3-scheduled-example/ – george

+0

Спасибо. Я понял это, и на самом деле не хотел догадываться, где в вашем ответе был ответ. – arcy

0

Ниже приведена конфигурация метода в bean-компоненте для выполнения согласно расписанию CRON-строк с использованием конфигурации XML.

Нам нужно:

  1. задача боб, который определяет класс, который конкретизируется и запустить,
  2. триггер боб, который определяет, как часто запускать и задача боб с шага 1,
  3. в кварцевого компонента, чтобы запустить триггер с шага 2 по расписанию триггера.

Вот конфигурации, как у меня, поставленные в 'applicationContext.xml':

В 'applicationContext.xml' для приложения, я ставлю следующие бобы:

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

Тогда класс MyRefreshTask был записан следующим образом:

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

Это произвело линию (один из) лог-файл (ы) каждую минуту. Мне бы очень хотелось узнать, как предсказать, какой файл журнала будет содержать вывод System.out из разных частей приложения для Tomcat, но это на другой день.

Смежные вопросы