注入@Model bean的EJB会在每个请求上创建(GlassFish)

时间:2012-06-08 03:06:37

标签: java jsf glassfish ejb cdi

我无法在网上找到灵魂或任何对此的参考。这是问题

我有一个非常简单的网络项目

  • 的index.xhtml

    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:f="http://java.sun.com/jsf/core">
        <h:head>
            <title>Index</title>
        </h:head>
        <h:body>
            <h:form>
                <h:panelGrid>
                    <h:outputText value="#{myBean.message}" />
                    <h:inputText value="#{myBean.name}" />
                    <h:commandButton action="#{myBean.sayHello()}"
                                     value="Say Hello">
                        <f:ajax execute="@form" render="@form" />
                    </h:commandButton>
                </h:panelGrid>
            </h:form>
        </h:body>
    </html>

  • MyBean.java


    import javax.enterprise.inject.Model;
    import javax.inject.Inject;

    @Model
    public class MyBean
    {
        @Inject 
        private MyEJB myEjb;

        public MyBean()
        {
            System.out.println("Creating MyBean");
        }

        private String name;

        private String message;

        public void sayHello()
        {
            setMessage(myEjb.sayHello(getName()));
        }

        public String getMessage()
        {
            return message;
        }

        public void setMessage(String message)
        {
            this.message = message;
        }

        public String getName()
        {
            return name;
        }

        public void setName(String name)
        {
            this.name = name;
        }
    }

  • MyEJB.java


    import javax.ejb.Stateless;

    @Stateless
    public class MyEJB
    {

        public MyEJB()
        {
            System.out.println("Creating MyEJB");
        }

        public String sayHello(String name)
        {
            return "Hello " + name;
        }

    }

这项工作正常但是glassfish日志显示了这个

信息:创建MyBean 信息:创建MyBean 信息:创建MyEJB 信息:创建MyBean 信息:创建MyEJB 信息:创建MyEJB

一次请求。

这意味着MyBean在请求上创建了3次而MyEJB创建了3次

如果这是一种正常行为,我会徘徊,或者这是玻璃鱼上的一个错误,或者我在这里做了一些非常错误的事情,因为如果在每次请求中创建和销毁这么多对象,那么应用程序会遇到问题。

如果我改成像这样的更经典的aproche


    import javax.ejb.EJB;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.RequestScoped;

    @RequestScoped
    @ManagedBean
    public class MyBean
    {
        @EJB
        private MyEJB myEjb;

        public MyBean()
        {
            System.out.println("Creating MyBean");
        }

        private String name;

        private String message;

        public void sayHello()
        {
            setMessage(myEjb.sayHello(getName()));
        }

        public String getMessage()
        {
            return message;
        }

        public void setMessage(String message)
        {
            this.message = message;
        }

        public String getName()
        {
            return name;
        }

        public void setName(String name)
        {
            this.name = name;
        }
    }


输出不同

我创建了1个ejb,然后该实例处理了其余的请求 每个请求都会创建一次MyBean。

请帮助我也许我错过了cdi规范。

感谢

1 个答案:

答案 0 :(得分:1)

调试EJB / CDI / JSF / ...组件的构造函数是一个假的朋友。

在现代框架中,幕后有很多东西 - 相当多的东西都在使用Java反射 - 你不能依赖对构造函数的调用来表明你有新鲜感和即用型组件。

您需要做的是使用适当的生命周期钩子之一。这些明确设计为在创建/销毁/解除钝化/钝化组件之后/之前调用。

在您的情况下,请使用@PostConstructdocumentation here