在 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.
相关文章