Впрыскивая весенний фасоль с использованием CDI @inject

StackOverflow https://stackoverflow.com/questions/4144039

Вопрос

Я пытаюсь ввести фасоль, определенный в контексте пружины в управляемый компонент CDI, но я не успешен. Фасоль не вводится, вместо того, чтобы новый экземпляр создан каждый раз, когда необходимо выполнить инъекцию. Моя среда - TOMCAT 7 с сварным швом JBoss.

Весна ApplicationContext является Stereighforward:

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

Управленческий Bean CDI выглядит так:

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

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

  ...

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

}

Это мое 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>

Однако, когда я получаю доступ к test Собственность на странице JSF, новый Test Экземпляр создается каждый раз, когда возникает доступ. Это простой пример:

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

Я получаю следующий вывод:

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

После обновления:

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

Я вижу, что первый вывод является правильным. Неважно, как часто я обновляю страницу, testFromSpring Возвращает значение из компонента, определенного в контексте пружины. Однако второй вывод ясно показывает, что каждый раз getTest Метод на test Компоненты вызываются, новый Test Экземпляр создан и вводится вместо того, чтобы использовать экземпляр из пружинного контекста, как я ожидал.

Итак, в чем причина этого поведения?

Как я могу ввести боб от пружинного контекста в управляемый CDI Bean?

Я также попробовал использовать квалификатор, используя имя, определенное в контексте пружины, но теперь исключение, указывающее, что фасоль не может быть найден:

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

для кода

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

  @javax.inject.Inject
  @javax.inject.Named("testFromSpring")
  private Test myTest = null;
Это было полезно?

Решение

Pascal - это правильно, что вы не можете вводить что-то, управляемое пружину в сварную фасоль (или наоборот).

Но вы можете определить производителя, который получает весну бобы и дает им сваривать. Это звучит как экстремальный взлом, кстати, и я не думаю, что вы должны использовать оба рамки в одном проекте. Выберите один и удалите другой. В противном случае вы получите несколько проблем.

Вот как это будет выглядеть так.

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

Тогда вы можете иметь:

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

PS Вы можете сделать вышеперечисленный типовой безопасностью. Вместо того, чтобы получить фасоль по имени, вы можете получить, через рефлексию, общий тип точки впрыска, и посмотрите на нем в контексте пружины.

Другие советы

Я не думаю, что шва может ввести что-то, что не управляется (создается) сварным швом (весной фасоль в вашем случае).

Также есть проект Snowdrop JBOSS. Я не знаю, будет ли это работать с JBoss Weld на Tomcat, документация описывает только на JBOSS 5, 6 и 7. в соответствии с http://docs.jboss.org/snowdrop/2.0.0.final/html/ch03.html#d0e618. Он будет вводить бобы, объявленные в JBoss-Spring.xml в местах, помеченные @spring вместо @inject. Нет опыта себя, хотя, YMMV.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top