web-dev-qa-db-fra.com

Démarrage printanier ajouter un nouveau travail de planification dynamiquement

J'écris une application Spring Boot

Mes exigences sont les suivantes - Dans le dossier resources (src/main/resources) si j’ajoute de nouveaux fichiers XML. Je devrais lire ces fichiers et obtenir une URL et d’autres paramètres spécifiques à chacun d’eux. et pour les URL, j'ai besoin de télécharger des données tous les jours. Ainsi, un nouveau travail de planificateur commencera par l'URL et certains paramètres. 

Les nouveaux travaux seront exécutés à des heures différentes, en utilisant l’expression cron présente dans les fichiers xml De plus, les fichiers seront ajoutés dynamiquement à tout moment Comment l’implémenter. 

7
F K M N

Si vous souhaitez planifier des tâches de manière dynamique, vous pouvez le faire sans ressort en utilisant ExecutorService en particulier ScheduledThreadPoolExecutor

Runnable task  = () -> doSomething();
ScheduledExecutorService executor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());
// Schedule a task that will be executed in 120 sec
executor.schedule(task, 120, TimeUnit.SECONDS);

// Schedule a task that will be first run in 120 sec and each 120sec
// If an exception occurs then it's task executions are canceled.
executor.scheduleAtFixedRate(task, 120, 120, TimeUnit.SECONDS);

// Schedule a task that will be first run in 120 sec and each 120sec after the last execution
// If an exception occurs then it's task executions are canceled.
executor.scheduleWithFixedDelay(task, 120, 120, TimeUnit.SECONDS);

Avec spring, vous pouvez compter sur API de tâches et de planification

public class MyBean {

    private final TaskScheduler executor;

    @Autowired
    public MyBean(TaskScheduler taskExecutor) {
        this.executor = taskExecutor;
    }

    public void scheduling(final Runnable task) {
        // Schedule a task to run once at the given date (here in 1minute)
        executor.schedule(task, Date.from(LocalDateTime.now().plusMinutes(1)
            .atZone(ZoneId.systemDefault()).toInstant()));

        // Schedule a task that will run as soon as possible and every 1000ms
        executor.scheduleAtFixedRate(task, 1000);

        // Schedule a task that will first run at the given date and every 1000ms
        executor.scheduleAtFixedRate(task, Date.from(LocalDateTime.now().plusMinutes(1)
            .atZone(ZoneId.systemDefault()).toInstant()), 1000);

        // Schedule a task that will run as soon as possible and every 1000ms after the previous completion
        executor.scheduleWithFixedDelay(task, 1000);

        // Schedule a task that will run as soon as possible and every 1000ms after the previous completion
        executor.scheduleWithFixedDelay(task, Date.from(LocalDateTime.now().plusMinutes(1)
            .atZone(ZoneId.systemDefault()).toInstant()), 1000);

        // Schedule a task with the given cron expression
        executor.schedule(task, new CronTrigger("*/5 * * * * MON-FRI"));
    }
}

Et vous pouvez fournir votre propre déclencheur en implémentant Trigger

N'oubliez pas d'activer la planification en utilisant @EnableScheduling sur la classe de configuration.

À propos de l’écoute du contenu du répertoire, vous pouvez utiliser WatchService . Quelque chose comme:

final Path myDir = Paths.get("my/directory/i/want/to/monitor");
final WatchService watchService = FileSystems.getDefault().newWatchService();
// listen to create event in the directory
myDir.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
// Infinite loop don't forget to run this in a Thread
for(;;) {
   final WatchKey key = watchService.take();
   for (WatchEvent<?> event : key.pollEvents()) {
       WatchEvent<Path> watchEvent = (WatchEvent<Path>) event;
       Path newFilePath = myDir.resolve(watchEvent.context());
       //do something with the newFilePath
    }
    // To keep receiving event
    key.reset();
}

Jetez un oeil à cet article: Regarder un répertoire pour les changements pour plus de détails.

23
JEY

Vous pouvez le faire sur une annotation de printemps:

@Scheduled(fixedRate = 360000)
public void parseXmlFile() {
    // logic for parsing the XML file.
}

Veuillez noter que la méthode doit être void. De plus, dans votre classe principale, vous devez activer la planification:

@SpringBootApplication
@EnableScheduling
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class);
    }
}

Veuillez voir la référence complète ici: https://spring.io/guides/gs/scheduling-tasks/

1
dave0688