2
votes

Existe-t-il une manière appropriée d'utiliser @PostConstruct dans Micronaut?

J'essaye d'imprimer un message après le démarrage de l'application avec @PostConstruct , mais rien n'est imprimé.

package dev.renansouza.server;

import javax.annotation.PostConstruct;
import javax.inject.Singleton;

@Singleton
public class ServerService {

    @PostConstruct
    public void print() {
        System.out.println("Hello!");
    }
}

J'ai lu cela @ PostConstruct est paresseux. Est-ce que cela signifie que je dois faire autre chose pour que cela fonctionne?


1 commentaires

Vous devez faire quelque chose pour que ce bean soit initialisé. Par exemple, injectez ce service dans un contrôleur, puis envoyez une requête à ce contrôleur.


3 Réponses :


3
votes

Voir le projet sur https://github.com/jeffbrown/renansouzapostconstruct .

https://github.com/jeffbrown/ renansouzapostconstruct / blob / master / src / main / java / renansouzapostconstruct / ServerService.java

package renansouzapostconstruct;

import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.HttpStatus;

@Controller("/demo")
public class DemoController {

    private ServerService serverService;

    public DemoController(ServerService serverService) {
        this.serverService = serverService;
    }

    @Get("/")
    public HttpStatus index() {
        return HttpStatus.OK;
    }
}

https://github.com/jeffbrown/renansouzapostconstruct/blob/master/src/main/japostansstruct/renansouzouz DemoController.java

package renansouzapostconstruct;

import javax.annotation.PostConstruct;
import javax.inject.Singleton;

@Singleton
public class ServerService {

    @PostConstruct
    public void print() {
        System.out.println("Hello!");
    }
}

Lorsque vous démarrez l'application, vous ne verrez pas le message imprimé en standard car le bean de service n'a pas été initialisé. Envoyez une demande à http: // localhost: 8080 / demo / et vous verrez le message imprimé sur stdout.

J'espère que cela vous aidera.


0 commentaires

7
votes

Vous pouvez également utiliser l'annotation @EventListener pour obtenir ce que vous quoi, si l'utilisation de @PostConstruct n'est pas si importante pour vous.

Par exemple, dans votre cas, vous pouvez ajouter le code suivant dans n'importe quelle classe pour écouter l'événement de démarrage de l'application .

@EventListener
void onStartup(ServerStartupEvent event) {
    println("Hey, I work from anywhere in project..")
}

Le code partagé ci-dessus est en Groovy

Gardez à l'esprit que l'écouteur d'événements ajouté dans la classe d'application principale est généralement appelé en premier à partir de ce que j'ai observé.


7 commentaires

Sans savoir ce qu'il veut faire, comment savez-vous que @PostConstruct n'est pas la bonne chose à faire? Il existe des cas d'utilisation parfaitement valables pour l'utilisation de @PostConstruct .


Cela ne veut pas dire que nous ne sommes pas autorisés à partager les différentes approches de la question.


Renan déclare clairement qu'il essaie d'imprimer un message au démarrage de l'application, j'ai répondu sur cette partie.


De plus, je conviens que j'aurais dû commencer par une phrase différente.


J'ai supposé que l'impression du message n'était pas l'exigence réelle, mais était un moyen d'aider à démontrer le comportement observé.


Bonjour gars! Merci pour cette réponse rapide. Je construis une application / microservice qui décompressera les fichiers XML compressés et les rendra disponibles à la prochaine application / microservice. L'objectif principal avec @PostConstruct ou @EventListener est de créer les répertoires de travail. J'ai pensé à un contrôleur pour appeler une méthode de mon service pour le faire, mais l'application aura un frontal qui doit connaître tous les dossiers. Merci encore.


Si vous lisez un fichier volumineux ou une tâche potentielle de longue durée, ce n'est pas une bonne idée de le faire en postconstruct.



2
votes

Le problème (aka fonctionnalité) est, comme vous l'avez déjà mentionné, le chargement paresseux.

Je vois deux solutions:

  1. Vous devez faire quelque chose pour que ce bean soit initialisé.

  2. Changer la portée du bean de @Singleton à @Context

La documentation Micronaut des états @Context (voir https://docs.micronaut.io/latest/api/io/micronaut/context/annotation/Context.html )

La portée du contexte indique que le cycle de vie des classes est lié à celui du BeanContext et qu'il doit être initialisé et arrêté lors du démarrage et de l'arrêt du BeanContext sous-jacent.

Micronaut traite par défaut toutes les définitions de bean Singleton comme paresseuses et ne les chargera qu'à la demande. En annotant un bean avec @Context, vous pouvez vous assurer que le bean est chargé en même temps que le contexte.

package dev.renansouza.server;

import javax.annotation.PostConstruct;
import javax.inject.Scope;

@Scope
public class ServerService {

    @PostConstruct
    public void print() {
        System.out.println("Hello!");
    }
}


0 commentaires