Java,无状态会话bean

时间:2010-01-17 04:59:56

标签: java java-ee ejb-3.0

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

谢谢,
罗杰

4 个答案:

答案 0 :(得分: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可以检索预订并从另一个停止的地方继续。

答案 1 :(得分:1)

我经常看到无状态会话bean使用局部变量作为在bean中维护“全局”状态的一种方法(为了避免将数据从对象内的一个方法调用传递给另一个的繁重任务)。

话虽如此,这些在你的对象中基本上是全局变量,并且有助于滥用(因为它们在我见过的大多数情况下也是如此)。我倾向于建议避免它们。

有些情况下它们很有用,但是......你有特定的用例吗?

答案 2 :(得分:1)

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

答案 3 :(得分:0)

如何保存在SLSB启动时(即在构造函数中)初始化的最终实例变量。 我正在考虑在SLSB的构造函数中实例化的DAO属性,如下所示:

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

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

因此DAO可以直接在SLSB的方法中使用,并且不需要在每次需要DAO时创建DAO。当然,提供DAO是无状态的,通常就是这种情况。当然,可以按需提供与数据库的连接,并且从不存储在SLSB本身中。