无状态Bean的范围

时间:2015-02-27 14:36:11

标签: scope cdi postconstruct

我有一个无状态的bean,如下所示:

@Stateless
public class MyBean implements IMyBean {

    @Inject
    private SomeClass someClass;
    @EJB
    private MyRepository myRepository;
    @Production
    @Inject
    private SomeFacade someWorker;

    @PostConstruct
    private void init() {
       // some logic ...
    }

    // some more logic...
}

IMyBean注释了@Local。 我正在运行JBoss服务器。我有一个使用MyBean的.bat文件。只有在第一次执行这个bat文件时才会调用@PostConstruct。这是为什么?哪个范围有MyBean?看起来它至少是ApplicationScoped。我以为会是RequestScope ......

1 个答案:

答案 0 :(得分:4)

在成为CDI bean之前,您的bean是一个EJB。因此它遵循无状态EJB的生命周期。第一次请求时,容器会创建它并调用@PostConstruct回调。当它不再需要时,它不会被返回到EJB无状态池而被破坏,准备重用。 从CDI的角度来看,它是一个@Dependent bean:每次注入时都会重新创建CDI部分(代理),但EJB部分是由池中的EJB容器提供的。 查看CDI规范,与Lifecycle of stateless and singleton session beans相关的部分说明了有关创建的内容:

  

当一个Bean对象的create()方法表示无状态   调用session或singleton会话bean,容器创建和   返回会话的特定于容器的内部本地引用   豆。此引用不直接暴露给应用程序。

关于破坏:

  

调用destroy()方法时,容器只会丢弃   这个内部参考。

内部引用被丢弃,但EJB容器保留bean以供将来重用。 如果多个用户同时请求此bean,则可能会创建一个新EJB并调用@PostConstruct。所以从用户的角度来看,postConstruct调用可能看起来是随机的。

最好的解决方案是将您的无状态bean放在@ApplicationScoped中,以避免出现奇怪的行为。