Spring Boot 中是否有一个全局标志来禁用所有计划的作业?
Is there a global flag in Spring Boot to disable all the scheduled jobs?
我有两个 jobs
,第一个每 2 秒运行一次,第二个每 10 秒运行一次。
我在 application.properties
中设置了他们的 cron
表达式,并且知道可以通过将 cron
表达式修改为 application.properties
文件中的 "-"
来禁用每个作业。
但我真的很想知道 Spring Boot
中是否有一个全局标志可以单次禁用所有 jobs
?
尝试以下并在服务器启动时出错。
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath />
</parent>
application.properties
#global flag for all jobs
spring.enable.scheduling=false
jobs.greet.cron=0/2 * * * * ?
jobs.email.cron=0/10 * * * * ?
DemoApplication.java
@SpringBootApplication
@EnableScheduling
@ConditionalOnProperty(name = "spring.enable.scheduling", matchIfMissing = true, havingValue = "true")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
GreetJob.java
@Component
@Log4j2
public class GreetJob {
@Scheduled(cron = "${jobs.greet.cron}")
public void greet() {
log.info("Starting greet now...");
}
}
EmailJob.java
@Component
@Log4j2
public class EmailJob {
@Scheduled(cron = "${jobs.email.cron}")
public void sendEmail() {
log.info("Sending email now...");
}
}
异常:
2020-05-23 15:51:04,536 ERROR org.springframework.boot.SpringApplication [restartedMain] Application run failed
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:156)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
at com.example.DemoApplication.main(DemoApplication.java:27)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getWebServerFactory(ServletWebServerApplicationContext.java:203)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:179)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:153)
... 13 common frames omitted
没有。但我建议您将所有作业 bean 定义为有条件的,如下所示:
@ConditionalOnProperty(value="jobs.enabled", havingValue = "true", matchIfMissing = true)
@Component
@Log4j2
public class GreetJob {
...
}
在这种情况下,默认情况下将启用所有作业 bean,即使未定义 属性 jobs.enabled 也是如此。立即禁用 所有 作业,您可以在应用程序属性文件
中定义 属性
jobs.enabled=false
或者在命令行中定义这个属性:
-Djobs.enabled=false
默认情况下,没有这样的选项,但是如果您将 @EnableScheduling
放在人工创建的配置上 @Conditional
,则可以为该工具提供 "global" 标志它。
这样你就不需要通过在它们上放置 @Conditional
来更改已经定义的计划作业(在你的情况下是 GreetJob
和 EmailJob
)并且将为这个设施提供一个单一的管理点:
因此,要创建 "artificial" 配置,请创建以下内容:
@Configuration
@EnableScheduling
@ConditionalOnProperty(name="jobs.enabled", havingValue = "true")
public class ConditionalEnableScheduling {
}
这样,如果您使用 --jobs.enabled
启动应用程序,条件将 "trigger" 并且配置将加载,以便 "scheduling infra" 将被初始化
一般说明(只是为了回答的完整性):
- 从主 class
中删除 @EnableScheduling
- 确保扫描此配置(例如将其放在主要 class 旁边)
我有两个 jobs
,第一个每 2 秒运行一次,第二个每 10 秒运行一次。
我在 application.properties
中设置了他们的 cron
表达式,并且知道可以通过将 cron
表达式修改为 application.properties
文件中的 "-"
来禁用每个作业。
但我真的很想知道 Spring Boot
中是否有一个全局标志可以单次禁用所有 jobs
?
尝试以下并在服务器启动时出错。
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath />
</parent>
application.properties
#global flag for all jobs
spring.enable.scheduling=false
jobs.greet.cron=0/2 * * * * ?
jobs.email.cron=0/10 * * * * ?
DemoApplication.java
@SpringBootApplication
@EnableScheduling
@ConditionalOnProperty(name = "spring.enable.scheduling", matchIfMissing = true, havingValue = "true")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
GreetJob.java
@Component
@Log4j2
public class GreetJob {
@Scheduled(cron = "${jobs.greet.cron}")
public void greet() {
log.info("Starting greet now...");
}
}
EmailJob.java
@Component
@Log4j2
public class EmailJob {
@Scheduled(cron = "${jobs.email.cron}")
public void sendEmail() {
log.info("Sending email now...");
}
}
异常:
2020-05-23 15:51:04,536 ERROR org.springframework.boot.SpringApplication [restartedMain] Application run failed
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:156)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
at com.example.DemoApplication.main(DemoApplication.java:27)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getWebServerFactory(ServletWebServerApplicationContext.java:203)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:179)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:153)
... 13 common frames omitted
没有。但我建议您将所有作业 bean 定义为有条件的,如下所示:
@ConditionalOnProperty(value="jobs.enabled", havingValue = "true", matchIfMissing = true)
@Component
@Log4j2
public class GreetJob {
...
}
在这种情况下,默认情况下将启用所有作业 bean,即使未定义 属性 jobs.enabled 也是如此。立即禁用 所有 作业,您可以在应用程序属性文件
中定义 属性jobs.enabled=false
或者在命令行中定义这个属性:
-Djobs.enabled=false
默认情况下,没有这样的选项,但是如果您将 @EnableScheduling
放在人工创建的配置上 @Conditional
,则可以为该工具提供 "global" 标志它。
这样你就不需要通过在它们上放置 @Conditional
来更改已经定义的计划作业(在你的情况下是 GreetJob
和 EmailJob
)并且将为这个设施提供一个单一的管理点:
因此,要创建 "artificial" 配置,请创建以下内容:
@Configuration
@EnableScheduling
@ConditionalOnProperty(name="jobs.enabled", havingValue = "true")
public class ConditionalEnableScheduling {
}
这样,如果您使用 --jobs.enabled
启动应用程序,条件将 "trigger" 并且配置将加载,以便 "scheduling infra" 将被初始化
一般说明(只是为了回答的完整性):
- 从主 class 中删除
- 确保扫描此配置(例如将其放在主要 class 旁边)
@EnableScheduling