Imaginez le modèle DI simplifié suivant:solution propre pour l'instanciation CDI désireux
@ApplicationScoped
public class A {
private B b;
@Inject
public A(B b) {
this.B = b;
}
}
@ApplicationScoped
public class B {
private C c;
@Inject
public B(C c) {
this.C = c;
}
}
@ApplicationScoped
public class C {
@PostConstruct
public void start() {
// processing that should begin on startup
}
}
que je veuille C#start
d'être appelé à la fin de déploiement. Le modèle qui est généralement suggéré en ligne est celui présenté here mais cette solution: 1) ajoute trop de passe-partout, 2) ajoute un nouveau fichier texte pour l'extension, 3) recourt à la triche d'utiliser toString
uniquement pour déclencher le proxy B
instancier la fève B
réelle au-dessous qui, à son tour déclencher le proxy C
etc.
Depuis CDI 1.1, en ajoutant la méthode suivante pour A
est également une solution:
public void init(@Observes @Initialized(ApplicationScoped.class) Object init) {
B.toString();
}
Cela résout les deux premiers problèmes décrits ci-dessus mais je dois encore appeler une méthode factice sur B
de sorte que la chaîne d'instanciation/injection est déclenchée et finit par appeler la méthode annotée @PostConstruct
de C
. Est-ce qu'il me manque une solution plus propre à ce problème? CDI 2.0 répond-il à cela?
Il se peut que je manque quelque chose, mais pourquoi ne pas simplement ajouter la classe '@Observes @ Initialized' à' C' pour forcer 'C' à démarrer. –
C'est un bon point, mais idéalement je voudrais que l'instanciation des beans respecte la direction de la chaîne de dépendances. Avec votre solution, le bean C pourrait finir par être instancié sans aucune garantie que les beans A et B aient été instanciés. – papiomytoglou
C'est un couplage étroit, qui est l'un des objectifs contre DI. –