Java,无状态会话Bean

4

无状态会话Bean不维护状态。那么这是否意味着它们不应该有实例变量?

谢谢,
罗杰

4个回答

9
在这个上下文中,“状态”一词有点误导性。它所指的是“会话状态”,也就是说,如果客户端进行多个调用,会话bean就无法知道。想象一下一系列的调用:
- reserveSeatsOnFlight(); - chooseMealPreference(); - confirmBooking()。
你在这里拥有的是会话状态,这意味着第二个调用必须由与第一个调用相同的bean进行,否则它就没有意义了。这就是有状态会话bean所做的事情。
有状态会话bean可以具有实例变量,但那些本质上是全局的。如果您有一个无状态会话bean池(根据容器决定您可能有或可能没有),那些实例变量可能存在于从一个调用到下一个调用。因此通常要避免使用实例变量。有其他机制可以实现这种功能。
让我给你举个例子。想象一下在无状态会话bean中进行的这个调用:
public void bookFlight(List<Passsenger> passengers, FlightNumber flight, Date date) {
  ...
}

如果你将实例变量作为预订数量计数,并在每次调用时递增它,那么后续的调用可能会调用不同的bean,因此会看到不同的值。这就是我所说的它并不一定有意义的原因。

那么回到第一个例子,处理这个问题的一种方法是将状态传回给调用者:

public interface ReservationSystem {
  public int createNewBooking();
  public int reserveSeatsOnFlight(int bookingId, int seats);
  public int chooseMealPreference(int bookingId, ...)
  ...
}

看一下上面的内容,现在它不再有对话状态了吗?实际上它还是有状态的,但是现在被封装在你传递的bookingId中。无状态会话bean可以检索预订并从另一个bean离开的地方继续。


1

我经常看到无状态会话Bean使用局部变量来维护bean内的“全局”状态(以避免在对象内的一个方法调用到另一个方法时传递数据的繁琐任务)。

话虽如此,这些本质上是您对象内的全局变量,并且容易被滥用(正如我所见过的大多数情况一样)。 我倾向于建议避免使用它们。

当然也有它们有用的情况... 您有特定的用例吗?


1
一个无状态的bean可以像任何其他对象一样拥有实例变量。它只是不能使用它们来维护特定客户端的值...

0

关于持有在SLSB启动时初始化的final实例变量怎么样呢(即在构造函数中)。 我在考虑一个DAO属性,它在SLSB的构造函数中被实例化,像这样:

    @Stateless
    public class MyStatelessBean() {    
    private final CustomerDAO customerDAO;

        public MyStatelessBean() {
               // Initialization code goes here
               this.customerDAO = new CustomerDAO();
        }
    ...
    }

因此,DAO 可以直接在 SLSB 的方法中使用,而不必每次需要 DAO 时都创建它。当然,前提是 DAO 是无状态的,这通常是情况。与数据库的连接当然会根据需求提供,并且永远不会存储在 SLSB 本身中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接