Injizieren eines Spring-Bean mit CDI @Inject
-
30-09-2019 - |
Frage
Ich versuche, eine Bohne in einem Frühlings-Kontext in einen CDI definiert zu injizieren verwaltete Komponenten, aber ich bin nicht erfolgreich. Die Bohne ist nicht gespritzt, anstatt eine neue Instanz jedes Mal erstellt wird, soll die Injektion durchgeführt werden. Meine Umgebung ist Tomcat 7 mit JBoss Weld.
Der Frühling ist Application straighforward:
<beans>
...
<bean id="testFromSpring" class="test.Test" />
...
</bean>
Die CDI-Managed Bean sieht wie folgt aus:
@javax.inject.Named("testA")
public class TestA {
@javax.inject.Inject
private Test myTest = null;
...
public Test getTest() {
return this.myTest;
}
}
Das ist mein faces-config.xml
<faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version="2.0">
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
</faces-config>
Allerdings, wenn ich die test
Eigenschaft innerhalb einer JSF-Seite zugreifen, wird eine neue Instanz Test
wird jedes Mal erstellt wird, der Zugriff erfolgt. Dies ist ein einfaches Beispiel:
<html>
...
<p>1: <h:outputText value="#{testFromSpring}" /></p>
<p>2: <h:outputText value="#{testA.test}" /></p>
...
ich folgende Ausgabe:
1: test.Test@44d79c75
2: test.Test@53f336eb
Nach einem Refresh:
1: test.Test@44d79c75
2: test.Test@89f2ac63
kann ich sehen, dass die erste Ausgabe korrekt ist. Egal, wie oft ich die Seite aktualisieren, gibt der testFromSpring
den Wert aus der Bohne im Rahmen Frühling definiert. Jedoch ist die zweite Ausgabe zeigt deutlich, dass jedes Mal, wenn die getTest
Methode auf den test
Komponenten aufgerufen wird, wird eine neue Test
Instanz erstellt wird und injizierte, anstatt die Instanz aus dem Frühjahr Kontext der Verwendung, wie ich erwarten würde.
Also, was ist der Grund für dieses Verhalten?
Wie kann ich spritze die Bohne aus der Frühjahr Kontext in dem CDI Managed Bean?
Ich habe auch versucht, einen Qualifizierer mit dem Namen im Frühjahr Kontext definiert wird, aber jetzt wird eine Ausnahme angibt geworfen, dass die Bohne nicht gefunden werden kann:
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Injection point has unsatisfied dependencies. Injection point: field test.TestA.myTest; Qualifiers: [@javax.inject.Named(value=testFromSpring)]
für den Code
@javax.inject.Named("testA")
public class TestA {
@javax.inject.Inject
@javax.inject.Named("testFromSpring")
private Test myTest = null;
Lösung
Pascal ist richtig, dass man nicht spritzt etwas durch die Feder in eine Schweiß Bean verwaltet (oder umgekehrt).
Sie können aber einen Produzenten definieren, die Feder Bohnen bekommt und gibt ihnen zu verschweißen. Das klingt wie eine extreme Hack, btw, und ich glaube nicht, Sie sollen in einem Projekt beiden Frameworks verwenden. Wählen Sie ein und entfernen Sie die anderen. Sonst wirst du in mehrere Probleme bekommen.
Hier ist, wie es aussehen würde.
@Qualifier
@Retention(Runtime)
public @interface SpringBean {
@NonBinding String name();
}
public class SpringBeanProducer {
@Produces @SpringBean
public Object create(InjectionPoint ip) {
// get the name() from the annotation on the injection point
String springBeanName = ip.getAnnotations()....
//get the ServletContext from the FacesContext
ServletContext ctx = FacesContext.getCurrentInstance()...
return WebApplicationContextUtils
.getRequiredWebApplication(ctx).getBean(springBeanName);
}
}
Dann können Sie haben:
@Inject @SpringBean("fooBean")
private Foo yourObject;
P. S. Sie können die oben mehr typsicher machen. Statt namentlich die Bohne erhalten, können Sie erhalten, durch Reflexion, die Gattung des Injektionsstelle, und es im Frühjahr Kontext sehen.
Andere Tipps
Ich glaube nicht Weld etwas injizieren kann, die nicht verwaltet wird (instanziiert) durch Weld (einen Spring-Bean in Ihrem Fall).
Es gibt auch das JBoss Schneeglöckchen Projekt. Ich weiß nicht, ob es mit JBoss Weld auf Tomcat arbeiten wird, beschreibt die Dokumentation nur auf JBoss 5, 6 und 7. Nach http://docs.jboss.org/snowdrop/2.0.0.Final/html/ch03.html#d0e618 es Bohnen injizieren in jboss-spring.xml in Orten mit @Spring statt @Inject markiert erklärt. Keine Erfahrung mich aber YMMV.