J'utilise Spring Boot
et rencontrez des problèmes pour planifier un cron task
en utilisant des valeurs existantes dans la base de données.
Pour le moment, je lis les valeurs du fichier de propriétés comme ci-dessous:
@Scheduled(cron= "${time.export.cron}")
public void performJob() throws Exception {
// do something
}
Cela fonctionne bien, mais au lieu d'obtenir des valeurs du fichier de propriétés, je veux les obtenir de la table de base de données. Est-ce possible et comment?
vous pouvez ajouter un bean pour obtenir la valeur cron de la base de données dans la classe principale SpringBootApplication ou dans n'importe quelle classe de configuration. Un exemple de code est ci-dessous:
@Autowired
private CronRepository cronRepo;
@Bean
public int getCronValue()
{
return cronRepo.findOne("cron").getCronValue();
}
vous devez créer une table et fournir des valeurs appropriées dans la base de données. Après cela, vous pouvez fournir le bean dans le @Scheduled. Un exemple de code est ci-dessous:
@Scheduled(cron="#{@getCronValue}")
J'espère que cela fonctionne pour votre problème.
Pour atteindre vos objectifs, vous devez configurer votre planificateur lors de l'exécution. Cela signifie que vous devez utiliser davantage d'API de planificateur de bas niveau. Précisément lorsque vous avez déjà préparé la connexion avec votre base de données, vous pouvez configurer votre planificateur. Je pense que vous devez vous débarrasser de l'utilisation de l'annotation @Scheduled et gérer manuellement votre planificateur.
Je pense que ces sujets peuvent aider à décrire ce que je veux dire:
Comment changer @Scheduled fixedDelay de Spring lors de l'exécution
Planification d'un travail avec Spring par programmation (avec fixedRate défini dynamiquement)
Cependant, vous pouvez toujours utiliser des approches sauvages où vous intercepteriez la création du bean et remplaceriez l'annotation originale sur l'annotation par des métadonnées personnalisées, mais pour l'implémenter, vous devez connaître de nombreux détails du cadre et comment fonctionne le processeur d'annotation @Scheduled.
Vous devez charger les propriétés à partir de la table de base de données dans laquelle votre valeur est stockée. et fusionner les propriétés db avec les propriétés d'application
@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;
}
Pour plus d'aide, reportez-vous à https://analyzejava.wordpress.com/2015/01/16/loading-configuration-properties-from-database-in-spring-based-application/
L'utilisation de la méthode annotée @Bean fera l'affaire. Mais comme SpringBoot ne va appeler cette méthode qu'une seule fois et retourner la version mise en cache après cela, vous devrez redémarrer Spring pour obtenir une nouvelle valeur.
Pour obtenir un nouveau temps d'exécution à partir de la base de données, à l'aide de 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()
);
}
}
Remarque: n'utilisez pas @Scheduled de cette façon.