@Stateless和@Singleton之间的区别

god*_*nte 30 ejb ejb-3.1

我正在按照本教程使用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++;
    }    
}
Run Code Online (Sandbox Code Playgroud)

这是一个输出示例:


来自Facelets的Hello
消息是:84804258
计数器是:26
消息服务器Bean是:exercise1.MessageServerBean@757b6193


这是我的观察:

  • 当我设置bean时,@Stateless我总是得到相同的对象ID,并且计数器总是递增.
  • 当我设置bean时,@Stateful每次刷新页面时都会获得一个新实例.
  • 当我设置它时,@Singleton我得到的结果与我设置时@Stateless相同:相同的对象ID,计数器递增.

所以,我真正想要理解的是:在这种情况下@Stateless,@SingletonEJB 和EJB 之间的区别是什么?

gcv*_*cvt 40

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

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

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

  • 查看多个实例(而不是设置并发调用)的一种简单方法是从同一个无状态 bean 中调用无状态 bean。即:`@Stateless public class MyBean { @EJB MyBean bean; public void test() { System.out.println(this + ".test"); bean.test2(); } public void test2() { System.out.println(this + ".test2"); } }` (2认同)

kau*_*edg 35

根据Oracle文档:

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

单身人士不能被钝化:

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

该文档说明何时使用每种bean,Singleton bean具有以下内容:

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

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

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