Java 如何设置简单的Spring计划任务
以下是我认为来自Spring站点的相关文档: 34.2.2使用TaskExecutor Spring的TaskExecutor实现用作简单的JavaBean。在下面的示例中,我们定义了一个使用 ThreadPoolTaskExecutor异步打印一组消息Java 如何设置简单的Spring计划任务,java,spring,multithreading,spring-mvc,Java,Spring,Multithreading,Spring Mvc,以下是我认为来自Spring站点的相关文档: 34.2.2使用TaskExecutor Spring的TaskExecutor实现用作简单的JavaBean。在下面的示例中,我们定义了一个使用 ThreadPoolTaskExecutor异步打印一组消息 导入org.springframework.core.task.TaskExecutor; 公共类任务执行器示例{ 私有类MessagePrinterTask实现可运行{ 私有字符串消息; 公共消息PrinterTask(字符串消息){ thi
导入org.springframework.core.task.TaskExecutor;
公共类任务执行器示例{
私有类MessagePrinterTask实现可运行{
私有字符串消息;
公共消息PrinterTask(字符串消息){
this.message=消息;
}
公开募捐{
System.out.println(消息);
}
}
私有任务执行器任务执行器;
公共TaskExecutor示例(TaskExecutor TaskExecutor){
this.taskExecutor=taskExecutor;
}
公共消息(){
对于(int i=0;i<25;i++){
taskExecutor.execute(新的MessagePrinterTask(“Message”+i));
}
}
}
如您所见,您将Runnable添加到队列中,TaskExecutor使用其内部规则来决定任务何时执行,而不是从池中检索线程并自己执行
为了配置TaskExecutor将使用的规则,已经公开了简单的bean属性
我最终将不得不处理一个触发器,因为我想每N小时/分钟做一次,但目前我仍在关注这个示例。方法printMessages()
是如何执行的?我在配置或代码中没有看到任何提到它的地方
顺便说一下,这是文档中的完整小节:“34.2.2使用TaskExecutor”执行器和spring没有什么特别之处。在您发布的示例中,有一个bean使用run方法实现Runnable。在这里,您应该定义希望执行者运行的内容。在你的情况下是这样的
public void run() {
System.out.println(message);
}
然后你有一个执行者,它将通过
taskExecutor.execute(new MessagePrinterTask("Message" + i));
如果您想知道需要在哪里调用这一行(调用该方法),那么它实际上取决于您的应用程序和您正在尝试执行的操作。在您的示例中,无论何时调用printMessages(),您的任务都将在一个循环中执行25次
现在您已经提到了触发器以及如何设置它。我的建议如下。为要执行的所有任务创建简单的POJO,这些任务实现如下接口
public interface Poller extends Runnable
{
Trigger getTrigger();
}
在所有这些类中,实现run任务(要执行的内容)+getTrigger方法,该方法定义了任务所需的触发器,然后在config类中,您需要像这样注册它们
@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());
}
}
}
@配置
@使能调度
公共类配置实现SchedulingConfigurer
{
//自动连线所有轮询器
@自动连线
私人名单调查者;
@Bean(destromethod=“shutdown”)
公共执行者任务执行者()
{
返回Executors.newScheduledThreadPool(25);
}
@凌驾
公共无效配置任务(ScheduledTaskRegistrar任务注册器)
{
taskRegistrator.setScheduler(taskExecutor());
用于(轮询器轮询器:轮询器)
{
//注册要执行的任务和触发器
taskRegistrar.addTriggerTask(poller,poller.getTrigger());
}
}
}
这将自动开始使用所需的触发器执行所有任务。我希望这是有意义的。遗嘱执行人和弹簧没有什么特别之处。在您发布的示例中,有一个bean使用run方法实现Runnable。在这里,您应该定义希望执行者运行的内容。在你的情况下是这样的
public void run() {
System.out.println(message);
}
然后你有一个执行者,它将通过
taskExecutor.execute(new MessagePrinterTask("Message" + i));
如果您想知道需要在哪里调用这一行(调用该方法),那么它实际上取决于您的应用程序和您正在尝试执行的操作。在您的示例中,无论何时调用printMessages(),您的任务都将在一个循环中执行25次
现在您已经提到了触发器以及如何设置它。我的建议如下。为要执行的所有任务创建简单的POJO,这些任务实现如下接口
public interface Poller extends Runnable
{
Trigger getTrigger();
}
在所有这些类中,实现run任务(要执行的内容)+getTrigger方法,该方法定义了任务所需的触发器,然后在config类中,您需要像这样注册它们
@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());
}
}
}
@配置
@使能调度
公共类配置实现SchedulingConfigurer
{
//自动连线所有轮询器
@自动连线
私人名单调查者;
@Bean(destromethod=“shutdown”)
公共执行者任务执行者()
{
返回Executors.newScheduledThreadPool(25);
}
@凌驾
公共无效配置任务(ScheduledTaskRegistrar任务注册器)
{
taskRegistrator.setScheduler(taskExecutor());
用于(轮询器轮询器:轮询器)
{
//注册要执行的任务和触发器
taskRegistrar.addTriggerTask(poller,poller.getTrigger());
}
}
}
这将自动开始使用所需的触发器执行所有任务。我希望这是有意义的。下面使用XML配置在bean中配置一个方法,以根据CRON字符串计划运行 我们需要:
<!-- 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>
这每分钟在(其中一个)日志文件中产生一行。我很想知道如何预测哪个日志文件将最终包含Tomcat应用程序不同部分的System.out输出,但这是另一天的事情。下面将bean中的一个方法配置为根据CRON字符串运行