JavaBean将创建多次

JavaBean将创建多次,java,jakarta-ee,javabeans,Java,Jakarta Ee,Javabeans,我想使用企业JavaBeans创建一个web日历。所以我编写了一个类CalendarBean,它是stateful(@stateful)。作为一个属性,我使用一个deque来存储所有的日期。或者,我可以在最后或最初添加一个新年。 在JSP中,我使用-标记。 每次调用JSP时,都会创建一个新的Bean实例。每次它都会创建一个新的deque 我怎样才能预防它?我只需要一个Bean实例,就像一个单例 在有状态会话Bean中,实例变量表示唯一客户端Bean会话的状态。因此,每个客户机都有自己的实例。如果

我想使用企业JavaBeans创建一个web日历。所以我编写了一个类CalendarBean,它是stateful(@stateful)。作为一个属性,我使用一个deque来存储所有的日期。或者,我可以在最后或最初添加一个新年。 在JSP中,我使用
-标记。 每次调用JSP时,都会创建一个新的Bean实例。每次它都会创建一个新的deque


我怎样才能预防它?我只需要一个Bean实例,就像一个单例

在有状态会话Bean中,实例变量表示唯一客户端Bean会话的状态。因此,每个客户机都有自己的实例。如果您想要Bean的实例,可以使用Statefull会话Bean或Singleton会话Bean。 你可以看到:

参见文章。它说:

容器在注入期间创建了一个
@Stateful
bean

因此,当JSP被编译成ran时,容器将注入一个新的
CalenderBean

如果希望bean是单例的,最好声明将其注释为
@Stateless
,并使其成为无状态的:其行为不应依赖于任何实例变量的状态。这意味着,如果两个线程同时访问bean,它们就不能通过修改实例变量来影响bean彼此的行为方式

例如,如果您的CalenderBean有一个实例变量
private Calendar Calendar
,并且您的实例方法执行如下操作:

this.calendar.set(Calendar.YEAR, input.getYear()); // where input is a parameter
                                                   // to the method you were calling
return calendar.get(Calendar.ERA);
现在想象两个访问者在完全相同的情况下访问您的网页,但他们有不同的输入:

  • 用户1有
    input.getYear()
    is
    2000
  • 用户2有
    input.getYear()
    -5
由于我们无法保证这两个线程将按顺序处理,因此可能会发生以下情况:

  • 为用户1服务的线程将年份设置为
    2000
  • 为用户2服务的线程将年份设置为
    -5
  • 为用户1服务的线程设置纪元并返回
    gregorianalendar.BC

这显然是错误的:用户1影响了用户2的
CalendarBean
工作方式,这样,bean就不是无状态的。

,用户不应该能够通过调用JSP中的方法来更改bean?无状态没有达到我希望的效果(见顶部注释),如果我使用@Singleton,也不会发生任何事情。现在我创建了一个新Bean,它有一个实例变量(own)Calendar,即singleton。所以我的名单只会产生一次。我必须使用同步..:(-可能是范围内的问题?我必须选择“会话”而不是“请求”
scope
属性只说明bean可能被找到或应该被存储的位置。如果使用
会话
,这意味着两个连续的HTTP请求将具有相同的实例,而
请求
将暗示每个HTTP请求(即使在同一会话中)我现在的解决方案是:我不再使用@EJB引用,而是将@EJB引用集成到一个servlet中,该servlet将转发到JSP。所以我知道,这只是Bean的一个实例。