在 Spring Boot IntegrationTest 上禁用 @Schedule
如何在 Spring Boot IntegrationTest 上禁用计划自动启动?
How can I disable the schedule auto-start on Spring Boot IntegrationTest?
谢谢.
推荐答案
请注意,外部组件可能会自动启用调度(参见 HystrixStreamAutoConfiguration 和 MetricExportAutoConfiguration 来自 Spring 框架).因此,如果您尝试在指定 @EnableScheduling 的 @Configuration 类上使用 @ConditionalOnProperty 或 @Profile,那么由于外部组件,无论如何都会启用调度.
Be aware that external components could be enabling scheduling automatically (see HystrixStreamAutoConfiguration and MetricExportAutoConfiguration from the Spring Framework). So if you try and use @ConditionalOnProperty or @Profile on the @Configuration class that specifies @EnableScheduling, then scheduling will be enabled anyway due to external components.
有一个 @Configuration 类可以通过 @EnableScheduling 进行调度,然后将你的调度作业放在单独的类中,每个类都使用 @ConditionalOnProperty 来启用/禁用包含@Scheduled 任务的类.
Have one @Configuration class that enables scheduling via @EnableScheduling, but then have your scheduled jobs in separate classes, each of those using @ConditionalOnProperty to enable/disable the classes that contain the @Scheduled tasks.
不要将 @Scheduled 和 @EnableScheduling 放在同一个类中,否则您将遇到外部组件启用它的问题,因此 @ConditionalOnProperty 被忽略.
Don't have the @Scheduled and @EnableScheduling in the same class, or you will have the issue where external components are enabling it anyway, so the @ConditionalOnProperty is ignored.
例如:
@Configuration
@EnableScheduling
public class MyApplicationSchedulingConfiguration {
}
然后在一个单独的类中
@Named
@ConditionalOnProperty(value = "scheduling.enabled", havingValue = "true", matchIfMissing = false)
public class MyApplicationScheduledTasks {
@Scheduled(fixedRate = 60 * 60 * 1000)
public void runSomeTaskHourly() {
doStuff();
}
}
这个解决方案的问题是每个计划的作业都需要在它自己的类中,并指定 @ConditionalOnProperty.如果您错过了该注释,那么作业将运行.
The issue with this solution is that every scheduled job needs to be in it's own class with @ConditionalOnProperty specified. If you miss that annotation, then the job will run.
扩展 ThreadPoolTaskScheduler 并覆盖 TaskScheduler 方法.在这些方法中,您可以检查作业是否应该运行.
Extend the ThreadPoolTaskScheduler and override the TaskScheduler methods. In these methods you can perform a check to see if the job should run.
然后,在您使用@EnableScheduling 的@Configuration 类中,您还创建一个名为taskScheduler 的@Bean,它返回您的自定义线程池任务调度程序.
Then, in your @Configuration class where you use @EnableScheduling, you also create a @Bean called taskScheduler which returns your custom thread pool task scheduler).
例如:
public class ConditionalThreadPoolTaskScheduler extends ThreadPoolTaskScheduler {
@Inject
private Environment environment;
// Override the TaskScheduler methods
@Override
public ScheduledFuture<?> schedule(Runnable task, Trigger trigger) {
if (!canRun()) {
return null;
}
return super.schedule(task, trigger);
}
@Override
public ScheduledFuture<?> schedule(Runnable task, Date startTime) {
if (!canRun()) {
return null;
}
return super.schedule(task, startTime);
}
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period) {
if (!canRun()) {
return null;
}
return super.scheduleAtFixedRate(task, startTime, period);
}
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period) {
if (!canRun()) {
return null;
}
return super.scheduleAtFixedRate(task, period);
}
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
if (!canRun()) {
return null;
}
return super.scheduleWithFixedDelay(task, startTime, delay);
}
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay) {
if (!canRun()) {
return null;
}
return super.scheduleWithFixedDelay(task, delay);
}
private boolean canRun() {
if (environment == null) {
return false;
}
if (!Boolean.valueOf(environment.getProperty("scheduling.enabled"))) {
return false;
}
return true;
}
}
使用我们的自定义调度程序创建 taskScheduler bean 并启用调度的配置类
Configuration class that creates the taskScheduler bean using our custom scheduler, and enables scheduling
@Configuration
@EnableScheduling
public class MyApplicationSchedulingConfiguration {
@Bean
public TaskScheduler taskScheduler() {
return new ConditionalThreadPoolTaskScheduler();
}
}
上面的潜在问题是您已经创建了对内部 Spring 类的依赖,因此如果将来有更改,您必须修复兼容性.
The potential issue with the above is that you've created a dependency on an internal Spring class, so if there are changes in the future, you'd have to fix compatibility.
相关文章