package study.ejb3.lifecycle.stateless; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; import javax.ejb.LocalBean; import javax.ejb.SessionContext; import javax.ejb.Stateless; /** * In EJB 3.x, to create a Stateless we need only a class with @Stateless annotation, doing * that all public methods of the bean will be exposed to the client; * If the bean exposes at least one interface, it needs to specify that it exposes a no-interface * view by using the @LocalBean annotation on the bean class. Otherwise, the client must use one * of its interface; * If we define the configuration of the bean with annotations and xml (ejb-jar.xml), the xml's * configurations will override the annotation's configurations; * The lifecycle callback methods is defined with Annotation, must be void and have no parameters; * We don't need the home interface anymore, the EJB is got from injection or JNDI lookup; * * With EJB 3.1, JNDI names have been specified so the code could be portable: * java:global[/<app-name>]/<module-name>/<bean-name>[!<fully-qualified-interface-name>] * <app-name>: name of the .EAR file, if is not used can be ommited * <module-name>: name of the .JAR file or the .WAR file * <bean-name>: name of the bean (default is the name of the class) * [!<fully-qualified-interface-name>]: if the EJB expose more than one interface we must use * the fully name. * * For this exemple will generate: * Remote: "java:global/EjbLifecycleStudy/EjbStatelessBean!study.ejb3.lifecycle.stateless.EjbStatelessRemote" * Local no-view: "java:global/EjbLifecycleStudy/EjbStatelessBean!study.ejb3.lifecycle.stateless.EjbStatelessBean" */ @Stateless @LocalBean // @TransactionAttribute(TransactionAttributeType.REQUIRED) is default // if the EjbStatelessRemote wasn't annotated with @Remote we could do this // @Remote(EjbStatelessRemote.class) public class EjbStatelessBean implements EjbStatelessRemote { /** * To get the SessionContext we can use the @Resource annotation. * In EJB 3.x we have 3 new methods: * > getTimerService: Returns the javax.ejb.TimerService interface (only * Stateless and Singleton can call, Stateful can't be timed object); * > lookup: Enables the session bean to look up its environment entries * in the JNDI naming context; * > wasCancelCalled: Checks whether a client invoked the cancel() method on the client * Future object corresponding to the currently executing asynchronous business method. */ @Resource private SessionContext ctx; /** * We can inject environment entries with @Resource annotation. * The objects are injected before the Container call the method annotated with @PostConstruct. */ @Resource(name = "maxDiscount") private String maxDiscount; /** * @PostConstruct: Marks a method to be invoked immediately after a bean instance is created and dependency * injection is done by the Container. * This method is like the old ejbCreate(). */ @PostConstruct public void postConstruct() { System.out.println("postConstruct"); } /** * @PreDestroy: Marks a method to be invoked immediately before the bean instance is destroyed by the container. * This method is called by the Container to indicate that the bean will be * destroyed, so here we should release any resource used by the bean. * This method with @PreDestroy annotation correspond to the ejbRemove() method used in EJB 2.x. */ @PreDestroy public void preDestroy() { System.out.println("preDestroy"); } /** * A business method. */ public void doStuff() { System.out.println("Inside a business method!"); } }