我想使用 Enterprise Java Beans 创建一个 Web 日历。所以我编写了一个有状态的 CalendarBean 类(@Stateful)。作为一个属性,我使用双端队列来存储所有日期。或者,我可以在最后或开始时添加新的一年。在 JSP 中,我使用<jsp:useBean>
-Tag。在每次调用 JSP 时,都会创建一个新的 Bean 实例。每次它创建一个新的双端队列。
我该如何预防?我只想要一个像 Singleton 一样的 Bean 实例。
我想使用 Enterprise Java Beans 创建一个 Web 日历。所以我编写了一个有状态的 CalendarBean 类(@Stateful)。作为一个属性,我使用双端队列来存储所有日期。或者,我可以在最后或开始时添加新的一年。在 JSP 中,我使用<jsp:useBean>
-Tag。在每次调用 JSP 时,都会创建一个新的 Bean 实例。每次它创建一个新的双端队列。
我该如何预防?我只想要一个像 Singleton 一样的 Bean 实例。
在有状态会话 Bean 中,实例变量表示唯一客户端 bean 会话的状态。因此,每个客户端都有自己的实例。如果你想要 Bean 的实例,你可以使用 Statefull Session bean 或 Singleton Session bean。你可以看到:http ://docs.oracle.com/javaee/5/tutorial/doc/bnbly.html
请参阅Java EE 6 中的上下文和依赖注入一文。它说:
@Stateful
在注入过程中,容器会创建一个bean。
因此,当您的 JSP 编译运行时,容器将注入一个新的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);
现在想象两个访问者在完全相同的实例中访问您的网页,但他们有不同的输入:
input.getYear()
的是2000
input.getYear()
的是-5
由于我们不能保证这两个线程将被顺序处理,因此可能会发生以下情况:
2000
-5
GregorianCalendar.BC
。这显然是错误的:用户 1 影响了CalendarBean
用户 2 的工作方式,这样,bean 就不是无状态的。