7

我们知道无状态会话 Bean 不以任何方式保持状态。那么在无状态会话 Bean 中拥有一个全局变量有什么意义呢?为什么它没有在规范中被阻止(以避免不必要的混淆)?

如果拥有全局变量有任何实际好处,请用一段代码片段进行解释。

4

2 回答 2

8

A quote from the EJB 3.1 spec

4.7 Stateless Session Beans

Stateless session beans are session beans whose instances have no conversational state. This means that all bean instances are equivalent when they are not involved in servicing a client-invoked method.

The term “stateless” signifies that an instance has no state for a specific client. However, the instance variables of the instance can contain the state across client-invoked method calls.

Examples of such state include an open database connection and an object reference to an enterprise bean object.

The emphasis is on no conversational state. They can have "other" state.


For example, I have used it to check if the load was spread equally over all instances in a cluster node:

@Stateless(name = "DemoPingSb")
@Remote(DemoPingSbIfc.class)
public class DemoPingSb implements Serializable, DemoPingSbIfc {
    private final AtomicInteger instancePingCount = new AtomicInteger(0);
    private final static AtomicInteger classPingCount = new AtomicInteger(0);

    public DemoPingSb() {
        super();
    }

    public String ping(final String s) {
        final int local = this.instancePingCount.incrementAndGet();
        final int global = classPingCount.incrementAndGet();

        System.out.println("INFO: local " + local + ", global " + global
                + ", s " + s);

        return s.toUpperCase();
    }
}

and if there is enough load:

13:13:21,769 INFO [stdout] (http-localhost-127.0.0.1-8080-1) INFO: local 22, global 22, s hello
13:13:21,936 INFO [stdout] (http-localhost-127.0.0.1-8080-1) INFO: local 1, global 23, s hello

So there are some special cases where this feature might be useful.

Remarks

  • The spec talks about instance variables; the usage of a static variables is not covered there. So the code might not be correct regarding classPingCount
  • The usage of an AtomicInteger for instancePingCount could by replaced with volatile int, because (4.10.13)

The container must ensure that only one thread can be executing a stateless or stateful session bean instance at any time.

  • A stateless session bean is never passivated (4.2)
于 2013-08-02T12:00:18.890 回答
0

显然,任何答案都必须说明无状态会话 EJB 不得在对 EJB 上的方法的调用之间保持状态。

与其在 EJB 中通过禁止实例变量采取强硬方法,不如允许 EJB 开发人员定义它们以用于中间存储。也许有中间值,并且正在调用内部私有方法;开发人员(可以说是懒惰的)可能只使用实例变量,而不是传递参数和/或创建要在短期内传递的“即时状态对象”。

此处的关键(由规范解决)是,EJB 开发人员在任何情况下都不应假定任何此类字段将跨 EJB 的调用维护有意义的信息

于 2013-08-02T04:04:29.010 回答