Pregunta

Estoy tratando de inyectar un grano definido en un contexto de primavera en un CDI componente administrado, pero no estoy éxito. El frijol no se inyecta, en lugar de una nueva instancia se crea cada vez que la inyección debe ser realizada. Mi entorno es Tomcat 7 con JBoss Weld.

El ApplicationContext resorte está straighforward:

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

Los CDI logrado frijol es similar al siguiente:

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

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

  ...

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

}

Esta es mi 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>

Sin embargo, cuando accedo a la propiedad test desde dentro de una página JSF, una nueva instancia Test se está creando cada vez que se produce el acceso. Este es un ejemplo simple:

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

Me sale el siguiente resultado:

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

Después de una actualización:

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

Me puede observar que la primera salida es correcta. No importa cuántas veces me actualiza la página, el testFromSpring devuelve el valor de la semilla se define en el contexto de primavera. Sin embargo, la segunda salida claramente muestra que cada vez que se invoca el método getTest en los componentes test, se crea una nueva instancia Test y se inyecta en lugar de utilizar la instancia del contexto del resorte lo que cabe esperar.

Así que, ¿cuál es la razón de este comportamiento?

¿Cómo puedo inyectar el grano del contexto de Primavera en el bean gestionado CDI?

También intentado utilizar un calificador usando el nombre definido en el contexto de primavera, pero ahora se produce una excepción que indica que el grano no se puede encontrar:

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

para el código

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

  @javax.inject.Inject
  @javax.inject.Named("testFromSpring")
  private Test myTest = null;
¿Fue útil?

Solución

Pascal es correcto que no se puede inyectar algo gestionado por resorte en un grano de soldadura (o viceversa).

Sin embargo, se puede definir un productor que obtiene granos de primavera y les da a soldar. Esto suena como un corte del extremo, por cierto, y no creo que se supone que usar las dos marcos en un proyecto. Elegir uno y retire el otro. De lo contrario obtendrá en múltiples problemas.

Así es como se vería así.

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

A continuación, puede tener:

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

P.S. Puede hacer que el anterior más de tipo seguro. En lugar de obtener el grano por su nombre, se puede obtener, a través de la reflexión, del tipo genérico del punto de inyección, y mirar hacia arriba en el contexto de la primavera.

Otros consejos

No creo Weld puede inyectar algo que no está gestionada (instancia) por soldadura (un grano de primavera en su caso).

También está el proyecto JBoss campanillas. No sé si funcionará con JBoss Weld en Tomcat, la documentación describe sólo en JBoss 5, 6 y 7. De acuerdo con http://docs.jboss.org/snowdrop/2.0.0.Final/html/ch03.html#d0e618 inyectará habas declarada en jboss- spring.xml en los lugares marcados con @Spring en lugar de @Inject. Sin experiencia a mí mismo, sin embargo, tu caso es distinto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top