使用CDI注入非托管类?

时间:2012-03-28 14:24:06

标签: java-ee jsf-2 cdi jboss-weld

我正在使用CDI(Weld)替换faces-config中的托管bean声明。

问题基本上是这样的:

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

我无法用@Named命名核心类,因为它显然不熟悉应用程序Web部分中的工件。

今天它们被指定为

    <managed-property>
        <property-name>UserData</property-name>
        <value>#{sessionScope.UserData}</value>
    </managed-property>

我正在努力阅读此内容,但我会感激一些帮助。

如何使用CDI(甚至是JSF2?)注入不是托管bean的托管属性?

将托管bean注入托管bean的工作完美无缺,CDI对我来说真的很有用,所以我希望尽快解决这个问题。

干杯

3 个答案:

答案 0 :(得分:2)

  

如何使用CDI注入不是托管bean的托管属性   (甚至是JSF2?)

如果我的问题正确无误,那么CDI-Extension就是您的选择。您可以做的是注册一个在启动时解析非CDI-Beans的扩展,将它们包装为AnnotatedType,从而使它们可用于注射。

看一下Weld documentation中的第16章,特别是16.6看起来非常像你的用例。

而且:不用担心“编写自己的扩展”听起来像是在攻击框架。 CDI的设计考虑了扩展概念,并且将您自己的代码注册为扩展非常简单和直接。

答案 1 :(得分:2)

我们的应用程序会在会话或应用程序启动时进入这些对象。我需要的只是一个从外部环境中获取它们并返回它们的生产者。我的解决方案如下:

Superproducer:

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

返回我的对象​​的实际生成器布局:

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

答案 2 :(得分:1)

根据评论的要求,以下是使用标准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>

以下是如何设置JSF 2.x注释以摆脱这种JSF 1.x样式的XML注册:

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;

    // ...
}