Java 在@modelbean中注入的EJB在每次请求时都会被创建(GlassFish)
我在网上找不到这个问题的答案或任何参考资料。问题就在这里 我有一个非常简单的网络项目Java 在@modelbean中注入的EJB在每次请求时都会被创建(GlassFish),java,jsf,glassfish,ejb,cdi,Java,Jsf,Glassfish,Ejb,Cdi,我在网上找不到这个问题的答案或任何参考资料。问题就在这里 我有一个非常简单的网络项目 index.xhtml 指数 MyBean.java import javax.enterprise.inject.Model; import javax.inject.Inject; @Model public class MyBean { @Inject private MyEJB myEjb; public
- index.xhtml
- 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;
}
}
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;
}
}
导入javax.enterprise.inject.Model;
导入javax.inject.inject;
@模型
公共类MyBean
{
@注入
私人医院;
公共MyBean()
{
System.out.println(“创建MyBean”);
}
私有字符串名称;
私有字符串消息;
公共空间
{
setMessage(myEjb.sayHello(getName());
}
公共字符串getMessage()
{
返回消息;
}
公共无效设置消息(字符串消息)
{
this.message=消息;
}
公共字符串getName()
{
返回名称;
}
公共void集合名(字符串名)
{
this.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;
}
}
导入javax.ejb.Stateless;
@无国籍
公共类
{
公共图书馆
{
System.out.println(“创建MyEJB”);
}
公共字符串sayHello(字符串名称)
{
返回“Hello”+name;
}
}
这是正确的,但glassfish日志显示了这一点
Información:创建MyBean
Información:创建MyBean
Información:创建MyEJB
Información:创建MyBean
Información:创建MyEJB
Información:创建MyEJB
只要一个请求
这意味着MyBean在请求中被创建了3次,MyEJB被创建了3次以上
我不知道这是一种正常的行为,还是glassfish上的一个bug,或者我在这里做了一些非常错误的事情,因为如果每个请求都创建和销毁了这么多对象,seriuos应用程序就会出现问题
如果我换成这样一个更经典的套路
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;
}
}
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;
}
}
导入javax.ejb.ejb;
导入javax.faces.bean.ManagedBean;
导入javax.faces.bean.RequestScope;
@请求范围
@ManagedBean
公共类MyBean
{
@EJB
私人医院;
公共MyBean()
{
System.out.println(“创建MyBean”);
}
私有字符串名称;
私有字符串消息;
公共空间
{
setMessage(myEjb.sayHello(getName());
}
公共字符串getMessage()
{
返回消息;
}
公共无效设置消息(字符串消息)
{
this.message=消息;
}
公共字符串getName()
{
返回名称;
}
公共void集合名(字符串名)
{
this.name=名称;
}
}
输出是不同的
我创建了1个ejb,然后请求的其余部分由该实例处理
对于每个请求,MyBean都会创建一次
请帮助我,也许我误解了cdi规范
感谢调试EJB/CDI/JSF/的构造函数。。。他是个假朋友 在现代框架中,有很多事情在幕后进行——其中相当一部分是使用Java反射的——并且您不能依赖对构造函数的调用来指示您有一个新的、随时可用的组件 您需要做的是使用一个适当的生命周期挂钩。它们被明确设计为在创建/销毁/解除钝化/钝化组件之后/之前调用
在您的情况下,使用
@PostConstruct
,.调试EJB/CDI/JSF/的构造函数。。。他是个假朋友
在现代框架中,有很多事情在幕后进行——其中相当一部分是使用Java反射的——并且您不能依赖对构造函数的调用来指示您有一个新的、随时可用的组件
您需要做的是使用一个适当的生命周期挂钩。它们被明确设计为在创建/销毁/解除钝化/钝化组件之后/之前调用
在您的情况下,请使用
@PostConstruct
。好的,很抱歉,首先它没有创建bean 3次,每个请求一次,我在浏览器上预告了f5,我通过添加@Named来解决EJB创建问题。但是我在我读过的任何cdi教程中都没有看到这个要求,所以我不明白第二个代码示例中没有什么“经典的”。第一个使用CDI进行注入,第二个使用JSF和EJB进行注入,这是两种截然不同的模型@模型是RequestScope和Named的CDI版本的快捷方式。是的,您的模型对象将被创建多次。好的,很抱歉,首先它没有创建bean 3次,每个请求一次,我在浏览器上使用了f5,我通过添加@Named来解决EJB创建问题。但是我在我读过的任何cdi教程中都没有看到这个要求,所以我不明白第二个代码示例中没有什么“经典的”。第一个使用CDI进行注入,第二个使用JSF和EJB进行注入,这是两种截然不同的模型@模型是RequestScope和Named的CDI版本的快捷方式。因此,您的模型对象将被多次创建。