以下是我认为是Spring网站的相关文档:
34.2.2使用TaskExecutor Spring的TaskExecutor实现用作简单的JavaBeans。在下面的示例中,我们定义了一个使用的bean 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; 34.2.2使用TaskExecutor&#34;
答案 0 :(得分:0)
执行者和春天没有任何幻想。在您发布的示例中,您已经获得了一个使用run方法实现Runnable的bean。在那里,您应该定义执行程序要运行的内容。在你的情况下它是
public void run() {
System.out.println(message);
}
然后你有一个执行者,它将通过
执行这项任务taskExecutor.execute(new MessagePrinterTask("Message" + i));
如果您想知道在哪里需要调用此行(调用方法),那么它实际上取决于您的应用以及您尝试做什么。在您的示例中,每当您调用printMessages()时,您的任务将在循环中执行25次。
现在您已经提到过触发器以及如何设置它。我的建议如下。为所有要执行的任务创建简单的pojos,实现类似的接口
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());
}
}
}
这应该会自动开始使用所需的触发器执行所有任务。我希望这是有道理的。
答案 1 :(得分:0)
以下配置bean中的方法,使用XML配置根据CRON字符串计划运行。
我们需要:
以下是像我这样的配置,放在'applicationContext.xml'中:
在应用程序的'applicationContext.xml'中,我放了以下bean:
<!-- 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" );
}
}
这每分钟在(一个)日志文件中生成一行。我很想知道如何预测哪个日志文件最终会包含Tomcat应用程序不同部分的System.out输出,但那是另一天。