Question

Je suis en train d'injecter un haricot défini dans un contexte de printemps dans un CDI géré par composant, mais je ne suis pas réussi. Le haricot est pas injecté, au lieu d'une nouvelle instance est créée chaque fois que l'injection doit être effectuée. Mon environnement est Tomcat 7 avec JBoss Weld.

Le printemps ApplicationContext est straighforward:

<beans>
  ...
  <bean id="testFromSpring" class="test.Test" />
  ...
</bean>

Le CDI géré ressemble haricots comme ceci:

@javax.inject.Named("testA")
public class TestA {

  @javax.inject.Inject
  private Test myTest = null;

  ...

  public Test getTest() {
    return this.myTest;
  }

}

Ceci est mon 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>

Cependant, quand j'accéder à la propriété test à partir d'une page JSF, une nouvelle instance de Test est créé chaque fois que l'accès se produit. Ceci est un exemple simple:

<html>
  ...
  <p>1: <h:outputText value="#{testFromSpring}" /></p>
  <p>2: <h:outputText value="#{testA.test}" /></p>
  ...

je reçois la sortie suivante:

1: test.Test@44d79c75
2: test.Test@53f336eb

Après un rafraîchissement:

1: test.Test@44d79c75
2: test.Test@89f2ac63

Je peux voir que la première sortie est correcte. Peu importe combien de fois j'actualisez la page, la testFromSpring renvoie la valeur de la fève définie dans le contexte du printemps. Cependant, la deuxième sortie clairement montre que chaque fois que la méthode getTest sur les composants de test est invoquée, une nouvelle instance de Test est créé et injecté au lieu d'utiliser l'instance du contexte de printemps que je me attends.

Alors, quelle est la raison de ce comportement?

Comment puis-je injecter la fève du contexte du printemps dans le bean géré CDI?

J'ai aussi essayé d'utiliser un qualificatif en utilisant le nom défini dans le contexte du printemps, mais maintenant une exception est levée indiquant, qui ne peut être trouvé la fève:

org.jboss.weld.exceptions.DeploymentException: WELD-001408 Injection point has unsatisfied dependencies.  Injection point:  field test.TestA.myTest;  Qualifiers:  [@javax.inject.Named(value=testFromSpring)]

pour le code

@javax.inject.Named("testA")
public class TestA {

  @javax.inject.Inject
  @javax.inject.Named("testFromSpring")
  private Test myTest = null;
Était-ce utile?

La solution

Pascal est juste que vous ne pouvez pas injecter quelque chose géré par ressort dans un grain de soudure (ou vice-versa).

Mais vous pouvez définir un producteur qui obtient des grains de printemps et leur donne à souder. Cela sonne comme un hack extrême, d'ailleurs, et je ne pense pas que vous êtes censé utiliser les deux cadres dans un projet. Choisissez l'une et retirez l'autre. Sinon, vous aurez à plusieurs problèmes.

Voici comment cela ressemblerait.

@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);
    }
}

Ensuite, vous pouvez avoir:

@Inject @SpringBean("fooBean")
private Foo yourObject;

P.S. Vous pouvez faire ce qui précède type plus de sécurité. Au lieu d'obtenir le grain par nom, vous pouvez obtenir, par la réflexion, le type générique du point d'injection, et le chercher dans le contexte du printemps.

Autres conseils

Je ne pense pas que la soudure peut injecter quelque chose qui est pas géré (instanciée) par soudure (un haricot printemps dans votre cas).

Il y a aussi le projet JBoss Snowdrop. Je ne sais pas si ça va marcher avec JBoss Weld sur Tomcat, la documentation ne décrit que sur JBoss 5, 6 et 7. Selon http://docs.jboss.org/snowdrop/2.0.0.Final/html/ch03.html#d0e618 il injectera des haricots a déclaré dans jboss-spring.xml dans des endroits marqués @Spring au lieu de @Inject. Aucune expérience moi-même si, YMMV.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top