简体   繁体   English

如何将CDI SessionScoped bean注入RequestScoped bean

[英]How to inject CDI SessionScoped bean into RequestScoped bean

I'm trying to write a simple login form with jsf and CDI. 我正在尝试使用jsf和CDI编写一个简单的登录表单。 the problem is when I inject my SessionScoped bean it doesn't work as I expect. 问题是当我注入SessionScoped bean时,它无法按预期工作。 This is my 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++;
    }
}

And this is my controller : 这是我的控制器:

@Named
@RequestScoped
public class LoginPageMg {
    @Inject
    LoginInfo lo;

    public LoginPageMg() {
    }


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

And a simple Jsf form which calls login function and shows counter field of LoginInfo class. 还有一个简单的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>

By clicking login button and debugging variables I can see "lo" is something like this : 通过单击登录按钮并调试变量,我可以看到“ lo”是这样的:

lo = {LoginInfo$Proxy$_$$_WeldClientProxy@16688}"com.mg.LoginInfo@703ec5d5" lo = {LoginInfo $ Proxy $ _ $$ _ WeldClientProxy @ 16688}“ com.mg.LoginInfo@703ec5d5”

On line int x=8 I can see "lo" variables didn't changed at all but in my jsf page I can see the counter increases every time I press login button and bean holds the value after refreshing the page. 在int x = 8的行上,我可以看到“ lo”变量根本没有变化,但是在我的jsf页面中,每次按下登录按钮时,计数器都增加了,刷新页面后bean保留了该值。

  1. What is WeldClientProxy? 什么是WeldClientProxy?
  2. Why there are two different instance of a SessionScoped bean? 为什么有两个不同的SessionScoped bean实例? Is that normal or I'm doing something wrong? 那是正常现象还是我做错了什么?
  3. How can I inject the same instance that jsf does? 如何注入与jsf相同的实例?

I'm using Wildfly 15 Jsf 2.3.4 CDI 1.1 我正在使用Wildfly 15 Jsf 2.3.4 CDI 1.1

I'm using Wildfly 15 Jsf 2.3.4 CDI 1.1 我正在使用Wildfly 15 Jsf 2.3.4 CDI 1.1

WildFly 15 means EE 8 compatilibity, hence it comes with CDI 2.0. WildFly 15意味着EE 8兼容,因此它带有CDI 2.0。

Now to answer as much as I can from your questions: 现在从您的问题中尽可能回答我:

What is WeldClientProxy? 什么是WeldClientProxy?

Weld is a CDI reference implementation used by majority of EE servers out there, including WildFly. Weld是大多数EE服务器(包括WildFly)使用的CDI参考实现。 WeldClientProxy is an internal construct it uses for injection of normal scoped beans (pretty much all except @Dependent ). WeldClientProxy是一个内部构造,用于注入普通作用域的bean(除@Dependent外,几乎所有其他bean)。 It is not an actual instance of the bean, you can think of it as an "wrapper" that knows how to retrieve actual contextual instance and delegates calls to it. 它不是bean的实际实例,您可以将其视为知道如何检索实际上下文实例并将委托委派给它的“包装器”。 This way you can reuse the proxy instance while still pointing to the correct instance under the hood (hence the reference doesn't need to change). 这样,您可以重用代理实例,同时仍然指向正确的实例(因此,引用无需更改)。

Why there are two different instance of a SessionScoped bean? 为什么有两个不同的SessionScoped bean实例? Is that normal or I'm doing something wrong? 那是正常现象还是我做错了什么?

There is only one, the client proxy isn't an actual instance. 只有一个,客户端代理不是实际实例。 You basically verified that by seeing the count increase every time and keeping state between requests. 您基本上可以看到每次count增加并保持请求之间的状态,从而验证了这一点。

How can I inject the same instance that jsf does? 如何注入与jsf相同的实例?

JSF doesn't actually inject anything, instead it uses expression language to find the bean based on its name. JSF实际上并没有注入任何东西,而是使用表达式语言根据其名称查找bean。 CDI allows you to define this name via @Named . CDI允许您通过@Named定义此名称。 JSF then gets to use the very same bean you are injecting, again via a proxy. 然后,JSF再次通过代理使用与您注入的相同的bean。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM