Java Spring引导:从数据库获取@Scheduled cron值
我正在使用Java Spring引导:从数据库获取@Scheduled cron值,java,spring-boot,cron,scheduled-tasks,Java,Spring Boot,Cron,Scheduled Tasks,我正在使用springboot,在使用数据库中现有的值调度cron任务时遇到问题 目前,我正在从属性文件中读取如下值: @Scheduled(cron= "${time.export.cron}") public void performJob() throws Exception { // do something } 这可以很好地工作,但我不想从属性文件中获取值,而是想从数据库表中获取它们。是否可能以及如何实现?要实现目标,必须在运行时配置调度程序。这意味着您需要使用更多的低级调度器
springboot
,在使用数据库中现有的值调度cron任务时遇到问题
目前,我正在从属性文件中读取如下值:
@Scheduled(cron= "${time.export.cron}")
public void performJob() throws Exception {
// do something
}
这可以很好地工作,但我不想从属性文件中获取值,而是想从数据库表中获取它们。是否可能以及如何实现?要实现目标,必须在运行时配置调度程序。这意味着您需要使用更多的低级调度器API。当您已经准备好连接数据库时,您就可以配置调度程序了。我认为您需要放弃使用@Scheduled注释,手动管理您的调度程序
我认为这些主题有助于描述我的意思:
但是,您可以使用通配符方法拦截bean创建并用自定义元数据替换注释上的原始注释,但为了实现它,您必须了解许多框架细节以及@Scheduled annatation processor的工作方式。您需要从包含值的数据库表中加载属性存储。
并将该数据库属性与应用程序属性合并
@Autowired
private DataSource dataSource;
@Autowired
private DatabaseConfiguration configuration;
@Bean(name = "propertyConfig")
public DatabaseConfiguration getDatabaseConfiguration() {
DatabaseConfiguration configuration = new DatabaseConfiguration(dataSource, "propertyTable", "key", "value");
return configuration;
}
@Bean(name = "dbProperty")
public Properties getDBProperties(){
Properties properties = ConfigurationConverter.getProperties(configuration);
return properties;
}
有关更多帮助,请参考,您可以在SpringBootApplication主类或任何配置类中添加bean以从数据库获取cron值。示例代码如下:
@Autowired
private CronRepository cronRepo;
@Bean
public int getCronValue()
{
return cronRepo.findOne("cron").getCronValue();
}
@Scheduled(cron="#{@getCronValue}")
您应该创建一个表,并在数据库中提供合适的值。之后,您可以在@Scheduled
中提供bean。示例代码如下:
@Autowired
private CronRepository cronRepo;
@Bean
public int getCronValue()
{
return cronRepo.findOne("cron").getCronValue();
}
@Scheduled(cron="#{@getCronValue}")
希望它能解决您的问题。使用@Bean注释的方法就可以了。但由于SpringBoot只调用此方法1次,然后返回缓存版本,所以需要重新启动Spring以获取新值
要使用SchedulingConfigurer从数据库获取新的运行时,请执行以下操作:
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
@Autowired
private YourService yourService;
@Bean
public YourJob yourJob() {
return new YourJob();
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(
() -> yourJob().performJob(),
(TriggerContext triggerContext) -> yourService.getCron()
);
}
}
注意:不要以这种方式使用@Scheduled。对于spring,属性来自何处、文件、数据库、,git,只要它们最终是属性。我尝试实现一个从数据库中获取字符串值的方法,并尝试将此字符串注入@Scheduled,但它说:注释属性Scheduled.cron的值必须是常量表达式您不需要更改@Scheduled
上的任何内容,您只需要检索属性,并将它们传递到上下文:属性占位符
,或者如果您使用java配置,则使用ApplicationContextInitializer
添加PropertySource
来执行相同的操作。这对我来说很好,但我们需要在类级别添加@EnableScheduling来运行/执行@Scheduled(cron=“#{@getCronValue}”)美好的这对我帮助很大!谢谢。这很好,节省了我很多时间。非常感谢。我很好奇我是否正在更新DB上的cron time值,它是否会拾取最新的cron time还是旧的cron time?我尝试了这种方法,但我得到了一个错误“请求的bean当前正在创建中:是否存在无法解决的循环引用?”。这个解决方案的重点似乎是支持将来在不重新启动的情况下更改cron值,那么,当您的cron在数据库中发生更改时,您如何做到这一点呢?@KenClark每次cron作业触发时,它都会从数据库中读取数据,以便下次运行。