使用CDI @Inject注入Spring bean

我试图将在Spring上下文中定义的bean注入到CDI托管组件中,但没有成功。不会注入Bean,而是在每次执行注入时都会创建一个新实例。我的环境是带有JBoss Weld的Tomcat 7。

The Spring ApplicationContext is straighforward:

<beans>

...

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

...

</bean>

The CDI managed bean looks like this:

@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都会从Spring上下文中定义的bean中返回值。但是第二个输出清楚地表明,每次调用组件getTest上的方法时testTest都会创建并注入一个新实例,而不是像我期望的那样使用Spring上下文中的实例。

那么,这种行为的原因是什么呢?

如何将Spring上下文中的bean注入CDI托管bean中?

我还尝试过使用在Spring上下文中定义的名称来使用限定符,但是现在抛出异常,指示找不到该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是对的,你不能将spring管理的东西注入到焊接bean中(反之亦然)。

但是你可以定义一个生产者,该生产者获取春豆并将其提供给Weld。听起来,这是一个极端的技巧,我认为你不应该在一个项目中同时使用两个框架。选择一个,然后删除另一个。否则,你将遇到多个问题。

这是它的样子。

@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你可以使以上内容更加类型安全。无需按名称获取bean,而是可以通过反射获取注入点的通用类型,并在spring上下文中进行查找。

以上是 使用CDI @Inject注入Spring bean 的全部内容, 来源链接: utcz.com/qa/413066.html

回到顶部