Abhängigkeitsinjektion mit Konstruktorargumenten
-
26-12-2019 - |
Frage
Ich habe eine EJB wie folgt:
public class Bar() {
private String s;
public Bar() {
this.s = "bar";
}
@Inject public Bar(String s) {
this.s = s;
}
}
Wie kann ich diese Bohne mit dem injizieren? arg-Konstruktor in eine andere
Foo
Klasse?Dann definiere ich die
Foo
Klasse als EJB, mit dem Ziel, die auszuführen DI dafür in eine andere Klasse (zum Beispiel ein WebServlet).Wie kann ich ein spritzen?Foo
Klasseninstanz durch Übergabe von aString
richtig einzurichtenBar
arg-Konstruktor als innere Abhängigkeit?Gibt es eine bessere Möglichkeit, es zu definieren?
Bar
um die oben genannten Punkte zu erreichen?
Lösung
Die mit Anmerkungen versehene Konstruktorinjektion teilt CDI mit, dass immer dann, wenn jemand die Injektion einer Bar-Instanz anfordert, der mit @Inject markierte Konstruktor verwendet werden soll.
Der CDI-Container versucht dann, Instanzen für alle erforderlichen Konstruktorparameter abzurufen und schlägt fehl, da er mit „String“ nicht umgehen kann.Es weiß einfach nicht, welchen String Sie meinen.
Sie müssen dem Container dabei helfen, die Abhängigkeit aufzulösen, indem Sie einen Produzenten und einen Qualifizierer verwenden, um ihm mitzuteilen, welchen String Sie möchten.Ich gebe Ihnen hier nur die einfachste mögliche Lösung:
public class Bar {
@Inject
public Bar(@Named("myString") String s) {
this.s = s;
}
}
Und dann eine andere Klasse (muss keine andere Klasse sein, ist aber viel besser lesbar):
public class MyStringProducer {
@Produces
@Named("myString")
public String getMyString() {
return ...; // whatever you want ... read JSON, parse properties, randomize ...
}
}
Andere Tipps
@Inject
Funktioniert nur, wenn Sie spritzen.managed
„Objekte.String ist kein verwaltetes Objekt, daher funktioniert dies nicht.
Das folgende Beispiel sollte jedoch funktionieren (ich habe hier Spring verwendet).Verwenden Sie den DI-Initialisierungscode entsprechend der von Ihnen verwendeten Bibliothek):
@Named
public class Foo {
@Inject
Bar bar;
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext("com.pkg1");
Foo foo = (Foo)ctx.getBean("foo");
System.out.println(foo.bar.getString());
}
}
@Named
public class Bar {
private String s;
public Bar() {
this.s = "bar";
}
@Inject
public Bar(Bar1 bar1) {
this.s = bar1.getS();
}
public String getString() {
return s;
}
}
@Named
class Bar1 {
private String s="bar1";
public String getS() {
return s;
}
}