Wednesday, September 3, 2008

Identify correct statements about the lifecycle of EJB instances, including the use of the @PostConstruct and @PreDestroy callback methods

SCBCD Objective: Identify correct and incorrect statements or examples about the lifecycle of all 3.0 Enterprise Bean instances, including the use of the @PostConstruct and @PreDestroy callback methods.

One of the things you need to understand about EJBs, especially Session Beans and Message Driven Beans, is that the lifecycle of these objects are managed by the application server. As a developer, you will never call the constructor of a Session bean, or invoke the finalize method on a Message Driven Bean. To do so would imply that you, the developer, have some part in managing the lifecycle of an EJB, and alas, you simply do not. Session Beans and Message Driven beans have their entire lifecycle managed by the application server, and there's nothing you, as a developer, can do about it.

Of course, as developers, sometimes it would be nice to do something, or take some action, or perform some type of initialization when the application server creates, or initializes, a real-live instance of one of the EJBs you have created. Similarly, it might be nice to perhaps release some resources, or perform some type of clean-up when a given EJB is take out of service by the EJB container. Certainly, this isn't an unreasonable request for a developer to ask, so as you could imagine, the EJB3 spec provides a very simple facility that allows the developer to respond to various EJB lifecycle events. This facility is known as lifecycle method interceptor callbacks.

Basically, if you want to perform some logic immediately after an EJB has been created by the EJB container, you simply code a method in your EJB bean class, and decorate that method with the @PostConstruct annotation. If you would like to have some funky logic performed immediately before an EJB is taken out of service and garbage collected, you simply code a method in the EJB bean class and decorate that method with the @PreDestroy annotation. It's all just that simple!


******************************

package com.mcnz.ejb;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.ejb.Stateful;

@Stateful
public class StatefulTimerBean implements StatefulTimerLocal {

private Long startTime;
public StatefulTimerBean() {System.out.print("Constructor");}

@PostConstruct
void negate() {
startTime = new Long(-1);
System.out.println("PostCreate");
}

@PreDestroy
void nullify() {
startTime = null;
System.out.println("PreDestroy");
}

public void start(){
startTime = System.currentTimeMillis();
}
public long getStartTime() {
return startTime;
}
public long getElapsedTime() {
return System.currentTimeMillis() - startTime;
}
public boolean isStarted() {
if (! (startTime > 0) ){return false;}
else {return true;}
}

@PrePassivate
public void customSave() {
System.out.println("Container is Passivating!");
}

@PostActivate
public void customLoad() {
System.out.println("Container has Activated!");
}
}

******************************

What types of EJBs can have lifecycle interceptor methods?

"Lifecycle callback interceptor methods may be defined for session beans and message driven beans.

Interceptor methods for lifecycle event callbacks can be defined on an interceptor class and/or directly on the bean class. The PostConstruct, PreDestroy, PostActivate, and PrePassivate annotations are used to define an interceptor method for a lifecycle callback event. If the deployment descriptor is used to define interceptors, the post-construct, pre-destroy, post-activate, and pre-passivate elements are used.

Lifecycle callback interceptor methods and business method interceptor methods may be defined on the same interceptor class. Lifecycle callback interceptor methods are invoked in an unspecified transaction and security context. Lifecycle callback interceptor methods may be defined on superclasses of the bean class or interceptor classes. However, a given class may not have more than one lifecycle callback interceptor method for the same lifecycle event. Any subset or combination of lifecycle callback annotations may be specified on a given class. A single lifecycle callback interceptor method may be used to interpose on multiple callback events (e.g., PostConstruct and PostActivate). Lifecycle callback interceptor methods defined on an interceptor class have the following signature:

void
(InvocationContext)

Lifecycle callback interceptor methods defined on a bean class have the following signature:

void
()

Lifecycle callback interceptor methods can have public, private, protected, or package level access. A lifecycle callback interceptor method must not be declared as final or static." -Core Contracts EJB 3 Document pg 305

No comments: