40

I'm following this tutorial which also uses an EJB:

package exercise1;

import java.util.Random;
import javax.ejb.Stateless;
import javax.inject.Named;

@Stateless
public class MessageServerBean {
    private int counter = 0;

    public String getMessage(){
        Random random = new Random();
        random.nextInt(9999999);
        int myRandomNumber = random.nextInt();
        return "" + myRandomNumber;
    }

    public int getCounter(){
        return counter++;
    }    
}

Here is an output example:


Hello from Facelets
Message is: 84804258
Counter is: 26
Message Server Bean is: exercise1.MessageServerBean@757b6193


Here's my observation:

  • When I set the bean as @Stateless I always get the same object ID and counter always increments.
  • When I set the bean as @Stateful I get a new instance every time I refresh the page.
  • When I set it to @Singleton I get the same results as when I set it to @Stateless: same object ID, counter incrementing.

So, what I actually would like to understand is: what's the difference between @Stateless and @Singleton EJBs in this very case?

4

2 回答 2

46

您看到的是相同的输出,因为一次只有一个客户端访问 EJB。应用程序服务器能够为每次调用回收相同的无状态 EJB 对象。如果您尝试并发访问——同时有多个客户端——你会看到新的无状态实例出现。

请注意,根据服务器负载,即使是同一客户端进行的两次连续方法调用也可能最终出现在不同的无状态 EJB 对象中!

对于单例 EJB,没有区别——每个应用程序始终只有一个实例,无论有多少客户端尝试访问它。

于 2013-01-22T19:12:05.200 回答
41

根据Oracle 文档:

单例会话 bean 提供与无状态会话 bean 类似的功能,但与它们的不同之处在于每个应用程序只有一个单例会话 bean,而不是无状态会话 bean 池,其中任何一个都可以响应客户端请求。与无状态会话 bean 一样,单例会话 bean 可以实现 Web 服务端点。

单例不能被钝化:

与无状态会话 bean 一样,单例会话 bean 永远不会被钝化,只有两个阶段,不存在和准备好调用业务方法(...)

该文档解释了何时使用每种 bean,并且 Singleton bean 具有以下内容:

单个企业 bean 需要由多个线程同时访问。

应用程序需要企业 bean 在应用程序启动和关闭时执行任务。

因此,对于您的示例,两个注释之间没有区别。

于 2013-01-22T18:08:36.153 回答