Java Spring Boot:从数据库中获取@Scheduled cron 值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37113327/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Boot : Getting @Scheduled cron value from database
提问by Daniel
I'm using Spring Boot
and have issues scheduling a cron task
using values existing in database.
我正在使用Spring Boot
并且在安排cron task
数据库中存在的使用值时遇到问题。
For the time being, I'm reading values from properties file like below :
目前,我正在从属性文件中读取值,如下所示:
@Scheduled(cron= "${time.export.cron}")
public void performJob() throws Exception {
// do something
}
This works nicely, but instead of getting values from properties file, I want to get them from database table. Is it possible and how ?
这很好用,但不是从属性文件中获取值,我想从数据库表中获取它们。有可能吗?
采纳答案by Vignesh
you can add a bean to get cron value from database in the SpringBootApplication main class or in any of the configuration class. Example code is below:
您可以在 SpringBootApplication 主类或任何配置类中添加一个 bean 从数据库中获取 cron 值。示例代码如下:
@Autowired
private CronRepository cronRepo;
@Bean
public int getCronValue()
{
return cronRepo.findOne("cron").getCronValue();
}
you should create a table and provide suitable values in the database. After that you can provide the bean inside the @Scheduled. Example code is below:
您应该创建一个表并在数据库中提供合适的值。之后,您可以在@Scheduled 中提供bean。示例代码如下:
@Scheduled(cron="#{@getCronValue}")
Hope it works for your issue.
希望它适用于您的问题。
回答by Alex
To achieve your goals you must configure your scheduler at runtime. It means you need to use more low-level scheduler API. Precisely when you have already prepared connect with your database you can configure your scheduler. I think you need to get rid of using @Scheduled annotation and manully manage your scheduler.
为了实现您的目标,您必须在运行时配置您的调度程序。这意味着您需要使用更多低级调度程序 API。准确地说,当您已经准备好连接到您的数据库时,您就可以配置您的调度程序。我认为您需要摆脱使用 @Scheduled 注释并手动管理您的调度程序。
I think these topics can help to describe what I mean:
我认为这些主题可以帮助描述我的意思:
However always you can use wild approaches where you would intercept the bean creation and replace original annotation on annotation with custom metadata but in order to implement it you must know many framework details and how @Scheduled annatation processor works.
然而,您总是可以使用疯狂的方法来拦截 bean 创建并用自定义元数据替换注释上的原始注释,但为了实现它,您必须了解许多框架细节以及@Scheduled annatation 处理器的工作原理。
回答by NIrav Modi
You need to load properties from the database table in which your value stored. and merge that db properties with application properties
您需要从存储您的值的数据库表中加载属性。并将该数据库属性与应用程序属性合并
@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;
}
For more help refer https://analyzejava.wordpress.com/2015/01/16/loading-configuration-properties-from-database-in-spring-based-application/
回答by FatalFzrry
Using @Bean annotated method will do the trick. But as SpringBoot only going to call this method 1 time, and return cached version after that, you will need to restart Spring to getting new value.
使用@Bean 注释方法可以解决问题。但是由于 SpringBoot 只会调用此方法 1 次,然后返回缓存版本,因此您需要重新启动 Spring 以获取新值。
To get new run time from database, using SchedulingConfigurer:
要从数据库获取新的运行时间,请使用 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()
);
}
}
Note: don't use @Scheduled with this way.
注意:不要以这种方式使用@Scheduled。