web-dev-qa-db-fra.com

Appeler une méthode après le démarrage de l'application Spring Boot

J'ai une Java application Spring Boot qui a un planificateur qui appelle une tâche asynchrone à partir d'un service. La tâche prend quelques minutes (généralement 3-5 minutes) pour se terminer.

La même méthode asynchrone du service peut également être appelée via une application d'interface utilisateur, en appelant l'API à partir du contrôleur de démarrage Spring.

Code:

Planificateur

@Component
public class ScheduledTasks {
  @Autowired
  private MyService myService;

  @Scheduled(cron = "0 0 */1 * * ?")
  public void scheduleAsyncTask() {
    myService.doAsync();
  }
}

Service

@Service
public class MyService {
  @Async("threadTaskExecutor")
  public void doAsync() {
    //Do Stuff
  }
}

Contrôleur

@CrossOrigin
@RestController
@RequestMapping("/mysrv")
public class MyController {
  @Autowired
  private MyService myService;

  @CrossOrigin
  @RequestMapping(value = "/", method = RequestMethod.POST)
  public void postAsyncUpdate() {
    myService.doAsync();
  }
}

Le planificateur exécute la tâche asynchrone toutes les heures, mais un utilisateur peut également l'exécuter manuellement à partir de l'interface utilisateur.

Mais, je ne veux pas que la méthode async s'exécute à nouveau si elle est déjà en cours d'exécution.

Pour ce faire, j'ai créé une table dans DB qui contient un indicateur qui continue lorsque la méthode est en cours d'exécution, puis il est désactivé une fois la méthode terminée.

Quelque chose comme ça dans ma classe de service:

@Autowired
private MyDbRepo myDbRepo;

@Async("threadTaskExecutor")
public void doAsync() {
  if (!myDbRepo.isRunning()) {
    myDbRepo.setIsRunning(true);
    //Do Stuff
    myDbRepo.setIsRunning(false);
  } else {
    LOG.info("The Async task is already running");
  }
}

Maintenant, le problème est que l'indicateur se bloque parfois pour diverses raisons (redémarrage de l'application, autre erreur d'application, etc.)

Donc, je veux réinitialiser l'indicateur dans DB chaque fois que l'application Spring Boot est déployée et chaque fois qu'elle redémarre.

Comment puis je faire ça? Existe-t-il un moyen d'exécuter une méthode juste après le démarrage de l'application Spring Boot, d'où je peux appeler une méthode de mon référentiel pour désactiver les indicateurs dans la base de données?

7
Sumit

Si vous voulez faire quelque chose après le démarrage de l'application entière et une utilisation prête ci-dessous exemple de

import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class ApplicationStartup 
implements ApplicationListener<ApplicationReadyEvent> {

  /**
   * This event is executed as late as conceivably possible to indicate that 
   * the application is ready to service requests.
   */
  @Override
  public void onApplicationEvent(final ApplicationReadyEvent event) {

    // here your code ...

    return;
  }

} // class

S'il suffit de crocheter après la création d'un seul bean, utilisez @PostConstruct comme suggéré par @loan M

1
madz

Dans votre cas particulier, vous devez réinitialiser la base de données après le déploiement de l'application, donc la meilleure façon de le faire est d'utiliser le Spring CommandLineRunner .

Spring Boot fournit une interface CommanLineRunner avec une méthode callback run () qui peut être invoquée au démarrage de l'application après l'instanciation du contexte de l'application Spring.

Les beans CommandLineRunner peuvent être définis dans le même contexte d'application et peuvent être commandés à l'aide de l'interface @Ordered ou de l'annotation @Order.

@Component
public class CommandLineAppStartupRunnerSample implements CommandLineRunner {
    private static final Logger LOG =
      LoggerFactory.getLogger(CommandLineAppStartupRunnerSample .class);

    @Override
    public void run(String...args) throws Exception {
        LOG.info("Run method is executed");
        //Do something here
    }
}

Réponse renvoyée depuis le site: https://www.baeldung.com/running-setup-logic-on-startup-in-spring

0