Впрыскивая весенний фасоль с использованием CDI @inject
-
30-09-2019 - |
Вопрос
Я пытаюсь ввести фасоль, определенный в контексте пружины в управляемый компонент 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.