Jakarta ee 用CDI注入非托管类?
我正在用CDI(Weld)替换faces配置中的托管bean声明 问题基本上是这样的: 项目结构分为“网络”和“核心”。Web具有声明为托管bean的bean。它们还声明了不是bean而是pojo(?)的属性。核心类是集成类、域类等 我不能用@Named命名核心类,因为它显然不熟悉应用程序web部件中的构件 今天,它们是这样指定的Jakarta ee 用CDI注入非托管类?,jakarta-ee,jsf-2,cdi,jboss-weld,Jakarta Ee,Jsf 2,Cdi,Jboss Weld,我正在用CDI(Weld)替换faces配置中的托管bean声明 问题基本上是这样的: 项目结构分为“网络”和“核心”。Web具有声明为托管bean的bean。它们还声明了不是bean而是pojo(?)的属性。核心类是集成类、域类等 我不能用@Named命名核心类,因为它显然不熟悉应用程序web部件中的构件 今天,它们是这样指定的 <managed-property> <property-name>UserData</property-nam
<managed-property>
<property-name>UserData</property-name>
<value>#{sessionScope.UserData}</value>
</managed-property>
用户数据
#{sessionScope.UserData}
我正在努力了解这一点,但希望能得到一些帮助
如何使用CDI(甚至JSF2)注入一个不是托管bean的托管属性
将托管bean注入托管bean的工作是完美的,CDI对我来说真的很好,所以我希望尽快解决这个问题
干杯
如何使用CDI注入不是托管bean的托管属性
(甚至是JSF2?)
如果我正确理解了您的问题,那么CDI扩展就是您的选择。您可以做的是注册一个扩展,该扩展在启动时解析您的非CDIBean,将它们包装为AnnotatedType
,从而使它们可以用于注入
看看《焊接》中的第16章,尤其是16.6看起来非常像你的用例
而且:如果“编写自己的扩展”听起来像是对框架的黑客攻击,那就不用担心了。CDI的设计考虑到了扩展的概念,将自己的代码注册为扩展是非常简单的 根据注释的要求,下面是使用标准JSF注释时的操作方法 鉴于此JSF 1.x托管bean注册:
<managed-bean>
<managed-bean-name>bean</managed-bean-name>
<managed-bean-class>com.example.Bean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>userData</property-name>
<value>#{sessionScope.userData}</value>
</managed-property>
</managed-bean>
package com.example;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
@ManagedBean
@RequestScoped
public class Bean {
@ManagedProperty("#{sessionScope.userData}")
private UserData userData;
// ...
}
我们的应用程序在会话或应用程序启动时初始化这些对象。我所需要的只是一个制作人,从外部上下文中获取并返回它们。我的解决办法如下: 超级生产者:
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
/**
* @author Karl Kildén
*
* Superclass that should be extended for other producers that uses ext context.
*/
public class BaseExtContextProducer {
@Inject
protected FacesContext facesContext;
// map used to get UserData objects
protected Map<String, Object> parameterMap = (Map<String, Object>) facesContext
.getExternalContext().getSessionMap();
// variable name i.e "your variable" + message is used for Exception messages
protected final String message = " may not be null";
}
使用JSF2注释,可以在
@ManagedBean
类的所需userData
属性上使用@ManagedProperty(#{sessionScope.userData}”)
。但不知道如何使用CDI。顺便说一下,您的实例变量名大写是错误的。它应该以小写字母开头。尝试注入时,错误消息被遗忘:org.jboss.weld.exceptions.DeploymentException:weld-001408在注入点[[field]@injectprivate com.wmdata.raindess.portal.ui.RPBaseController.FPUserData]具有限定符[@Default]的[FPUserData]类型的未满足依赖项]现在当古鲁自己不知道的时候,我很害怕。关于实例变量名,您是对的,我删去了名称中对其他人来说毫无意义的部分,以提高可读性。我只是没有像JSF那样广泛地使用CDI:)我所有的JSF托管bean都由JSF注释管理。faces配置中的托管属性很容易被JSF注释替换,如前所述。这些类中的一些在WEB-INF/classes中,而另一些在WEB-INF/lib中的jar中吗?读了一些之后,我肯定觉得这个答案是正确的。我需要另一个解决方案,但那是因为我没有在我的问题中正确指定术语。非常感谢。我最初觉得我必须使用这个基于el的解决方案,并且在规范之间有一个令人遗憾的混乱。很高兴我不用这么做。但是,对于jsf用户来说,您也是一个伟大的贡献者
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import org.jboss.weld.exceptions.NullInstanceException;
import com.wmdata.raindance.portal.annotation.qualifiers.FromExtContext;
import com.wmdata.raindance.portal.tool.UserMessage;
/**
*
* @author Karl Kildén
*
* This producer gets YourObject that is stored in the external context.
*/
public class YourObjectProducer extends BaseExtContextProducer {
@Produces
//Qualifiers, scopes etc
@ApplicationScoped @FromExtContext
public YourObject getYourObject() {
YourObject yourObject = (YourObject) parameterMap
.get(YourObject.getStaticName);
if (YourObject == null) {
// Suggestion: use enum or static name to avoid getting with "" for cleaner code
throw new NullInstanceException(null,
YourObject.getStaticName + message);
}
return userMessage;
}
}