如何将cdi sessionscoped bean注入requestscoped bean



我正在尝试使用JSF和CDI编写简单的登录表单。问题是当我注入我的会话bean时,它无法正常工作。这是我的豆

@Named
@SessionScoped
public class LoginInfo implements Serializable {
    private String uname;
    private String pass;
    private String pagename;
    private int count;
    public LoginInfo() {
    }
    public void increment() {
        count++;
    }
}

这是我的控制器:

@Named
@RequestScoped
public class LoginPageMg {
    @Inject
    LoginInfo lo;
    public LoginPageMg() {
    }

    public void login() {
        lo.increment();
        lo.setPagename("aaa");
        int x = 8;
    }
}

和一个简单的JSF表单,该表单调用登录功能并显示LoginInfo类的计数器字段。

<h:form prependId="false" id="mainform" styleClass="login-box">
                        <p:inputText value="#{loginPageMg.uname}"/>
                        <p:password value="#{loginPageMg.pass}"/>
                        <h:outputLabel id="counter" value="#{loginInfo.count}"></h:outputLabel>
                        <p:commandButton update="counter"
                                         action="#{loginPageMg.login}"
                                         value="login"></p:commandButton>
</h:form>

通过单击登录按钮和调试变量,我可以看到" lo"就是这样:

lo = {logininfo $ proxy $ _ $ _ $ _ weldclientproxy@16688}" com.mg.logininfo@703ec5d5"

在Line Int X = 8上,我可以看到" LO"变量完全没有更改,但是在JSF页面中,我可以看到每次按下登录按钮时,计数器都会增加,并且Bean在刷新页面后保持值。<<<<<<<<<<<<<</p>

  1. 什么是weldclientproxy?
  2. 为什么会有两个不同的实例?是那正常还是我做错了什么?
  3. 如何注入JSF的实例?

我正在使用 Wildfly 15 JSF 2.3.4 CDI 1.1

我正在使用野生蝇15 JSF 2.3.4 CDI 1.1

野生蝇15表示EE 8兼容,因此具有CDI 2.0。

现在从您的问题中尽可能多地回答:

什么是weldclientproxy?

焊缝是大多数EE服务器(包括Wildfly)使用的CDI参考实现。WeldClientProxy是一种内部结构,用于注入普通示波器豆(除了@Dependent以外,几乎全部)。它不是bean的实际实例,您可以将其视为知道如何检索实际上下文实例并委派给它的"包装器"。这样,您可以重复使用代理实例,同时仍指向引擎盖下的正确实例(因此,引用不需要更改)。

为什么会有两个不同的实例?那是正常的还是我做错了什么?

只有一个,客户端代理不是实际实例。您基本上通过看到count每次增加并在请求之间保持状态来验证。

我如何注入JSF的实例?

JSF实际上没有注入任何东西,而是使用表达式语言根据其名称找到BEAN。CDI允许您通过@Named定义此名称。然后,JSF再次使用您要注入的相同豆,再次通过代理。