如何在 spring 启动时安排 cron 作业而不使用 @Scheduled() 注释
How to schedule a cron job in spring boot without using @Scheduled() annotation
在 spring 引导中,我可以通过不对方法使用 @Scheduled
注释来安排 spring 作业吗?
我正在 spring 引导中处理 spring 作业。我想通过使用 cron 表达式来安排作业,但不对方法使用 @Scheduled(cron = " ")
注释。
我知道我可以在这个方法中安排一个工作,如下所示。
@Scheduled (cron = "0 10 10 10 * ?")
public void execute() {
/ * some job code * /
}
但我希望它是动态的,这样我就可以将 cron 表达式作为用户的输入并安排它。
我想出了一个工作示例,因为我发现您的问题很有趣并且之前一直对这个问题感兴趣。它完全基于源代码,所以我不知道它是否接近于遵循最佳实践。尽管如此,您可以根据自己的需要对其进行调整。仅供参考,您不一定需要创建一个新的 ScheduledTaskRegistrar 对象 - 我认为由于您的 objective 是一个动态调度程序,您不会对纯粹在覆盖方法中定义您的任务感兴趣。
@SpringBootApplication
public class TaskScheduler implements SchedulingConfigurer, CommandLineRunner {
public static void main(String[] args){SpringApplication.run(TaskScheduler.class, args);}
List<CronTask> cronTasks;
@Override
public void run(String... args) throws Exception {
CronTask task = this.createCronTask(new Runnable() {
@Override
public void run() {
System.out.println(LocalDateTime.now());
}
}, "1/10 * * * * *");
ScheduledTaskRegistrar taskRegistrar = new ScheduledTaskRegistrar();
taskRegistrar.addCronTask(task);
configureTasks(taskRegistrar);
Thread.sleep(51);
taskRegistrar.destroy();
taskRegistrar = null;
ScheduledTaskRegistrar taskRegistrar2 = new ScheduledTaskRegistrar();
taskRegistrar2.addCronTask(task);
configureTasks(taskRegistrar2);
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
// "Calls scheduleTasks() at bean construction time" - docs
taskRegistrar.afterPropertiesSet();
}
public CronTask createCronTask(Runnable action, String expression) {
return new CronTask(action, new CronTrigger(expression));
}
}
我有在 Azure 和其他地方使用 cron 作业的经验。在 Java 中编程,为了简单起见,我通常使用固定时间的 @Scheduled
。希望这对你有用。
这是我的工作示例,如果有人想在不使用 @Scheduled 注释的情况下使用 TaskScheduler
@配置Class
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
final Logger LOGGER = LogManager.getLogger(SchedulerConfig.class);
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
LOGGER.debug("Creating Async Task Scheduler");
scheduledTaskRegistrar.setTaskScheduler(taskScheduler());
}
// This is mandatory otherwise it will to be able to find bean of
// taskScheduler. Without this it was giving runtime error says, can not find
// taskScheduler bean.
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(20); // Better to read it from property file.
scheduler.setThreadNamePrefix("ThreadScheduler-");
scheduler.initialize();
return scheduler;
}
}
从应用程序 class 调用的调度程序 Class。
@Component
public class MyTaskScheduler {
private TaskScheduler taskScheduler;
// Here we are auto-wiring taskScheduler, that's why need to create
// taskScheduler bean in configuration class
@Autowired
public void setScheduler(TaskScheduler scheduler) {
this.taskScheduler = scheduler;
}
public void schedule() {
taskScheduler.scheduleWithFixedDelay(new Runnable(){
@Override
public void run() {
System.out.println("I am running after every 1 second");
}
}, 1000);
}
}
如果有任何机会 @Configuration
注释不起作用,那么将 @EnableConfigurationProperties
放在主 运行 class 中。
确保将 @EnableScheduling
放在 Application
class 处,这样主运行 class 看起来像
@SpringBootApplication
@EnableScheduling
@EnableConfigurationProperties
public class MainApplication implements CommandLineRunner {
@Autowired
MyTaskScheduler myTaskScheduler;
public static void main(String[] args) {
final Logger logger = LogManager.getLogger(MainApplication.class);
SpringApplication.run(MainApplication.class, args);
logger.info("Application started");
}
@Override
public void run(String... args) throws Exception {
myTaskScheduler.schedule();
}
}
在 spring 引导中,我可以通过不对方法使用 @Scheduled
注释来安排 spring 作业吗?
我正在 spring 引导中处理 spring 作业。我想通过使用 cron 表达式来安排作业,但不对方法使用 @Scheduled(cron = " ")
注释。
我知道我可以在这个方法中安排一个工作,如下所示。
@Scheduled (cron = "0 10 10 10 * ?")
public void execute() {
/ * some job code * /
}
但我希望它是动态的,这样我就可以将 cron 表达式作为用户的输入并安排它。
我想出了一个工作示例,因为我发现您的问题很有趣并且之前一直对这个问题感兴趣。它完全基于源代码,所以我不知道它是否接近于遵循最佳实践。尽管如此,您可以根据自己的需要对其进行调整。仅供参考,您不一定需要创建一个新的 ScheduledTaskRegistrar 对象 - 我认为由于您的 objective 是一个动态调度程序,您不会对纯粹在覆盖方法中定义您的任务感兴趣。
@SpringBootApplication
public class TaskScheduler implements SchedulingConfigurer, CommandLineRunner {
public static void main(String[] args){SpringApplication.run(TaskScheduler.class, args);}
List<CronTask> cronTasks;
@Override
public void run(String... args) throws Exception {
CronTask task = this.createCronTask(new Runnable() {
@Override
public void run() {
System.out.println(LocalDateTime.now());
}
}, "1/10 * * * * *");
ScheduledTaskRegistrar taskRegistrar = new ScheduledTaskRegistrar();
taskRegistrar.addCronTask(task);
configureTasks(taskRegistrar);
Thread.sleep(51);
taskRegistrar.destroy();
taskRegistrar = null;
ScheduledTaskRegistrar taskRegistrar2 = new ScheduledTaskRegistrar();
taskRegistrar2.addCronTask(task);
configureTasks(taskRegistrar2);
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
// "Calls scheduleTasks() at bean construction time" - docs
taskRegistrar.afterPropertiesSet();
}
public CronTask createCronTask(Runnable action, String expression) {
return new CronTask(action, new CronTrigger(expression));
}
}
我有在 Azure 和其他地方使用 cron 作业的经验。在 Java 中编程,为了简单起见,我通常使用固定时间的 @Scheduled
。希望这对你有用。
这是我的工作示例,如果有人想在不使用 @Scheduled 注释的情况下使用 TaskScheduler
@配置Class
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
final Logger LOGGER = LogManager.getLogger(SchedulerConfig.class);
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
LOGGER.debug("Creating Async Task Scheduler");
scheduledTaskRegistrar.setTaskScheduler(taskScheduler());
}
// This is mandatory otherwise it will to be able to find bean of
// taskScheduler. Without this it was giving runtime error says, can not find
// taskScheduler bean.
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(20); // Better to read it from property file.
scheduler.setThreadNamePrefix("ThreadScheduler-");
scheduler.initialize();
return scheduler;
}
}
从应用程序 class 调用的调度程序 Class。
@Component
public class MyTaskScheduler {
private TaskScheduler taskScheduler;
// Here we are auto-wiring taskScheduler, that's why need to create
// taskScheduler bean in configuration class
@Autowired
public void setScheduler(TaskScheduler scheduler) {
this.taskScheduler = scheduler;
}
public void schedule() {
taskScheduler.scheduleWithFixedDelay(new Runnable(){
@Override
public void run() {
System.out.println("I am running after every 1 second");
}
}, 1000);
}
}
如果有任何机会 @Configuration
注释不起作用,那么将 @EnableConfigurationProperties
放在主 运行 class 中。
确保将 @EnableScheduling
放在 Application
class 处,这样主运行 class 看起来像
@SpringBootApplication
@EnableScheduling
@EnableConfigurationProperties
public class MainApplication implements CommandLineRunner {
@Autowired
MyTaskScheduler myTaskScheduler;
public static void main(String[] args) {
final Logger logger = LogManager.getLogger(MainApplication.class);
SpringApplication.run(MainApplication.class, args);
logger.info("Application started");
}
@Override
public void run(String... args) throws Exception {
myTaskScheduler.schedule();
}
}