Lifecycle Management

The EJB container manages the life cycle of session beans based on callback annotations. Some of these annotations apply to all managed beans in general and some are applicable only to specific EJB types. All these annotations can only be applied to a single method only.

All you need to do is

  • Identify methods which need to be executed when a

    session bean reaches a particular life cycle stage (e.g. after is it

    constructed, prior to removal etc.)

  • Decorate those methods with an appropriate annotation which conveys

    information regarding the actual life cycle stage during which the

    method will receive a call back i.e. automatically invoked by the

    container

The @PostConstruct and @PreDestroy annotations belong to the Common Annotations specification i.e. they are not part of the EJB specification

@PostConstruct

All managed beans can enjoy the services rendered by @PostConstruct. Methods decorated with this annotation are automatically invoked by the container after the constructor invocation and dependency injection (if any) have been executed.

@PreDestroy

The method annotated with @PreDestroy annotation is called just before the container is about to discard the EJB instance. Just like @PostConstruct, this annotation can also be applied to any Managed Bean executing within the container (including EJBs)

The destruction of an EJB instance might happen under multiple scenarios (we are not covering this in depth). Also, the term destroy or discard in context of EJB instances refers to putting that particular instance out of service i.e. it is made available for garbage collection and will no longer be used by the EJB container to serve client requests

package ejbap.lcm;

import ejbap.core.StatelessBeanExample;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Stateless;
import javax.inject.Inject;

@Stateless
public class StatlessBeanBasicLCM {

    @Inject
    private StatelessBeanExample instance;

    @PostConstruct
    public void init(){
        System.out.println("Post construct callback invoked");
        System.out.println("Injected EJB instance - " + instance.hashCode());
    }

    @PreDestroy
    public void destroy(){
        System.out.println("I am about to be consumed by the GC !");
    }
}

The annotations discussed below are only to Stateful session beans i.e. beans decorated with @Stateful

@PrePassivate

A method annotated with this call back annotation instructs the container to invoke it before serializing the Stateful bean instance from memory to disk

@PostActivate

The container calls a method decorated with @PostActivate right after it brings a passivated stateful bean instance from disk back into the main memory

@Remove

When a method annotated with @Remove is invoked by the client of the stateful EJB instance, the container destroys it after completion of the method.

Unlike @PreDestroy, the @Remove is not a call back style annotation. Also, methods annotated with @PreDestroy (if any) will be invoked prior to destruction of the EJB instance

package ejbap.lcm.stateful;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.PrePassivate;
import javax.ejb.Stateful;
import java.sql.Connection;
import java.sql.SQLException;
import javax.ejb.PostActivate;
import javax.ejb.Remove;

@Stateful
public class StatefulBeanLCM {

    private Connection conn;

    @PostConstruct
    @PostActivate
    public void init(){
        //fetch a DB connection
        conn = getConnection();
    }

    @PreDestroy
    @Remove
    @PrePassivate
    public void close(){
        closeConnection();
    }

    private Connection getConnection(){
        //dummy method
        return null;
    }

    private void closeConnection(){
        try {
            conn.close();
        } catch (SQLException ex) {
            throw new RuntimeException(ex);
        }
    }

}

@StatefulTimeout

The container uses the value associated with the @StatefulTimeout annotation to determine the duration for which the bean instance can remain idle (without serving client requests). After the timeout threshold is crossed, the instance is a candidate for removal i.e. garbage collection and (subsequent) passivation

package ejbap.lcm.stateful;

import java.util.concurrent.TimeUnit;
import javax.ejb.Stateful;
import javax.ejb.StatefulTimeout;
import java.util.Date;

@Stateful
@StatefulTimeout(value = 1, unit = TimeUnit.MINUTES)
public class StatefulBeanTimeout {

    public String getTime(){
        return new Date().toString();
    }
}

You can use the value and unit elements of this annotation to define its behaviour

Configuration options

Here are a few examples

  • @StatefulTimeout(0) – this means that your bean instance will be

    removed immediately after the completion of the method which holds

    this annotation

  • @StatefulTimeout(-1) – your method will not be sensitive to time outs

  • @StatefulTimeout(15000) – method will wait for 15000 ms (15 seconds) for client requests before it becomes a candidate for eviction

The default value for the unit element is java.util.concurrent.TimeUnit.MILLISECONDS and a timeout value of less than -1 is invalid

A note on Life Cycle states

Assuming you have read through this chapter carefully, it should be clear that different EJBs undergo different stages in their life cycle. This section provides a summary of each states without diving in depth how they transition from one stage to another

Stateless EJB life cycle states

Distinct states associated with a Stateless EJB are

  • Does Not Exist: the bean does not yet exist in the EJB pool (has not been instantiated)

  • Ready: state where the EJB instance already exists in the EJB pool but is not servicing a client request

  • Active: the EJB instance is summoned in order to service a client request, and as a result it goes into a BUSY state

These states are also applicable to Message Driven Beans

Stateful EJB life cycle states

Stateful EJBs life cycle transitions are similar to their Stateless counterparts except for the addition of an additional stage

  • Does Not Exist: same as a Stateless bean

  • Ready: same as a Stateless bean

  • Active: same as a Stateless bean

  • Passivated: this stage is reached when the bean instance is removed from the container's main memory and serialized to disk (or any secondary storage supported by the container)

Singleton EJB life cycle states

These are the simplest of them all!

  • Does Not Exist: when the instance has not yet been created

  • Active: the bean is busy serving a request

Looking ahead ...

In the next chapter, we'll briefly look at how session beans are pooled by the EJB container

Last updated