package study.ejb3.lifecycle.singleton;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.AccessTimeout;
import javax.ejb.DependsOn;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Singleton;
import javax.ejb.Startup;
/**
* The EJB Singleton was introduced in EJB 3.1, is instantiated once per application.
* The Container will make sure only one instance is created by JVM.
* Singleton and Stateless share the same lifecycle, but Singleton stay alive until
* the Container is shut down. And the creation of Singleton depends whether it is
* annotated with @Startup or is referencered with @DependsOn, so the Container
* will create on deploytime, otherwise will be created when is used (a client calls
* a method).
*
* We can tell to the Container instantiate the class at startup of the application
* using @Startup.
* In some cases, when you have several singleton beans, explicit initialization ordering
* can be important. We can do that through @DependsOn.
*
* Is possible to control the concurrency access to the Singleton EJB. We can do that (BMC)
* or leave it to the Container (CMC);
* CMC - Container Managed Concurrency:
* @Lock(LockType.WRITE): A method associated with an exclusive lock will not allow
* concurrent invocations until the method’s processing is completed.
* @Lock(LockType.READ): A method associated with a shared lock will allow any number
* of other concurrent invocations to the bean’s instance.
* We can annotate a class (all methods) or a specific method.
*
* BMC - Bean Managed Concurrency:
* We control the concurrency access through Java synchronization.
*/
@Singleton
@Startup
@Lock(LockType.READ)
@DependsOn("EjbSingletonBMC")
public class EjbSingletonCMC {
public EjbSingletonCMC() {
System.out.println("EjbSingletonBean");
}
@PostConstruct
public void postConstruct() {
System.out.println("postConstruct");
}
@PreDestroy
public void preDestroy() {
System.out.println("preDestroy");
}
@Lock(LockType.READ)
public void doStuff() {
System.out.println("doStuff");
}
// Already is applyed because of the annotation in the class.
//@Lock(LockType.WRITE)
// timeout to a concurrency access blocked, the client will
// get a ConcurrentAccessTimeoutException
@AccessTimeout(20000)
public void doBar() {
System.out.println("doBar");
}
}