Jakarta ee 用CDI注入非托管类?

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

我正在用CDI(Weld)替换faces配置中的托管bean声明

问题基本上是这样的:

项目结构分为“网络”和“核心”。Web具有声明为托管bean的bean。它们还声明了不是bean而是pojo(?)的属性。核心类是集成类、域类等

我不能用@Named命名核心类,因为它显然不熟悉应用程序web部件中的构件

今天,它们是这样指定的

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