我正在尝试使用jsf和CDI编写一个简单的登录表单。 问题是当我注入SessionScoped 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”
在int x = 8上,我可以看到“ lo”变量根本没有变化,但是在我的jsf页面中,每当我按下登录按钮时,计数器的计数就会增加,并且bean在刷新页面后保持该值。 / p>
我正在使用 野蝇15 JSF 2.3.4 CDI 1.1
答案 0 :(得分:2)
我正在使用Wildfly 15 Jsf 2.3.4 CDI 1.1
WildFly 15表示EE 8兼容,因此它带有CDI 2.0。
现在就您的问题尽我所能回答
什么是WeldClientProxy?
Weld是一个CDI参考实现,供大多数EE服务器(包括WildFly)使用。 WeldClientProxy
是一个内部构造,用于注入正常范围的bean(除@Dependent
以外的几乎所有其他bean)。它不是bean的实际实例,您可以将其视为知道如何检索实际上下文实例并将委托委派给它的“包装器”。这样,您可以重用代理实例,同时仍然指向正确的实例(因此无需更改引用)。
为什么SessionScoped bean有两个不同的实例?那正常吗,或者我做错了什么?
只有一个,客户端代理不是实际实例。您基本上可以看到count
每次增加并保持请求之间的状态,从而证明了这一点。
如何注入与jsf相同的实例?
JSF实际上并没有注入任何东西,而是使用表达式语言根据其名称查找bean。 CDI允许您通过@Named
定义此名称。然后,JSF再次通过代理使用与您注入的相同的bean。