Your bean is an EJB before being a CDI bean. Therefore it follows the lifecycle of stateless EJB. The first time you request it, the container create it and call the @PostConstruct
callback. When it's not needed anymore, it's not destroyed by returned to the EJB stateless pool, ready to be reused.
From the CDI perspective it's a @Dependent
bean: it's CDI part (proxy) is recreated each time you inject it, but the EJB part is provided by the EJB container from the pool.
Looking at CDI spec, the section related to Lifecycle of stateless and singleton session beans states this regarding creation:
When the create() method of a Bean object that represents a stateless
session or singleton session bean is called, the container creates and
returns a container-specific internal local reference to the session
bean. This reference is not directly exposed to the application.
and regarding the the destruction:
When the destroy() method is called, the container simply discards
this internal reference.
Internal reference is discarded but the EJB container keep the bean for futur reuse.
If more than one user ask for this bean at the same time a new EJB might be created and the @PostConstruct
will be called. So from the user point of view postConstruct calls may seem random.
The best solution is to put your stateless bean in @ApplicationScoped
to avoid strange behavior.