Just as the entity bean has a well-defined life cycle, so does the stateless session bean. The stateless session bean’s life cycle has two states: Does Not Exist and Method-Ready Pool . The Method-Ready Pool is similar to the instance pool used for entity beans. This is one of the significant life-cycle differences between stateless and stateful session beans; stateless beans define instance pooling in their life cycle and stateful beans do not.[41] Figure 12-1 illustrates the states and transitions a stateless session bean instance goes through in its lifetime.
When a bean is in the Does Not Exist state, it is not an instance in the memory of the system. In other words, it has not been instantiated yet.
Stateless bean instances enter the Method-Ready Pool as the container needs them. When the EJB server is first started, it may create a number of stateless bean instances and enter them into the Method-Ready Pool. (The actual behavior of the server depends on the implementation.) When the number of stateless instances servicing client requests is insufficient, more can be created and added to the pool.
When an instance transitions from the Does
Not Exist state to the Method-Ready Pool, three operations are
performed on it. First, the bean instance is instantiated by invoking
the Class.newInstance()
method on the stateless
bean class.
Second, the
SessionBean.setSessionContext(SessionContext
context)
method is invoked on the bean instance.
This is when the instance receives its reference to the
EJBContext
for its lifetime. The
SessionContext
reference may be stored in a
nontransient instance field of the stateless session bean.
Finally, the no-argument
ejbCreate()
method is invoked on the bean
instance. Remember that a stateless session bean has only one
ejbCreate()
method, which takes no arguments. The
ejbCreate()
method is invoked only once in the
life cycle of the stateless session bean; when the client invokes the
create()
method on the EJB home, it is not
delegated to the bean instance.
Entity, session, and message-driven
beans must never define constructors. Take care of initialization
needs within ejbCreate()
and other callback
methods. The container instantiates instances of the bean class using
Class.newInstance()
, which requires a no-argument
constructor.
Stateless session beans are not subject to
activation, so they can maintain open connections to resources for
their entire life cycles.[42] The
ejbRemove()
method
should close any open resources before the stateless session bean is
evicted from memory at the end of its life cycle. You’ll read
more about ejbRemove()
later in this section.
Once an instance is in the Method-Ready Pool, it is ready to service client requests. When a client invokes a business method on an EJB object, the method call is delegated to any available instance in the Method-Ready Pool. While the instance is executing the request, it is unavailable for use by other EJB objects. Once the instance has finished, it is immediately available to any EJB object that needs it. This is slightly different from the instance pool for entity beans described in Chapter 11. In the entity instance pool, a bean instance might be swapped in to service an EJB object for several method invocations. Stateless session instances, however, are typically dedicated to an EJB object only for the duration of a single method call.
Although vendors can choose different strategies to support stateless
session beans, it is likely that they will use an
instance-swapping strategy
similar to that used for entity beans (see Chapter 11). However, the swap is very brief, lasting
only as long as the business method needs to execute. When an
instance is swapped in, its SessionContext
changes
to reflect the context of its EJB object and the client invoking the
method. The bean instance may be included in the transactional scope
of the client’s request and it may access
SessionContext
information specific to the client
request: for example, the security and transactional methods. Once
the instance has finished servicing the client, it is disassociated
from the EJB object and returned to the Method-Ready Pool.
Stateless session beans are not subject to activation and never have
their ejbActivate()
or
ejbPassivate()
callback methods invoked. The
reason is simple: stateless instances have no conversational state to
be preserved. (Stateful session beans do depend
on activation, as we’ll see later.)
Clients that need a remote or local reference to a stateless session
bean begin by invoking the create()
method on the
bean’s EJB home:
Object ref = jndiConnection.lookup("ProcessPaymentHomeRemote"); ProcessPaymentHomeRemote home = (ProcessPaymentHomeRemote) PortableRemoteObject.narrow(ref,ProcessPaymentHomeRemote.class); ProcessPaymentRemote pp = home.create();
Unlike the entity bean and stateful session bean, invoking the
create()
method does not result in a call to the
bean’s ejbCreate()
method. In stateless
session beans, calling the EJB home’s
create()
method results in the creation of an EJB
object for the client, but that is all.
A stateless session bean’s ejbCreate()
method is invoked only once in the life cycle of an
instance—when it is transitioning from the Does Not Exist state
to the Method-Ready Pool. It is not reinvoked every time a client
requests a remote reference to the bean. Stateless session beans are
limited to a single no-argument create()
method
because there is no way for the container to anticipate which
create()
method the client will invoke.
Bean instances leave the Method-Ready Pool for the
Does Not Exist state when the server no
longer needs them; that is, when the server decides to reduce the
total size of the Method-Ready Pool by evicting one or more instances
from memory. The process begins by invoking the
ejbRemove()
method on the instance. At this time,
the bean instance should perform any cleanup operations, such as
closing open resources. The ejbRemove()
method is
invoked only once in the life cycle of a stateless session
bean’s instance—when it is about to transition to the
Does Not Exist state. When a client invokes one of the remove methods
on a stateless session bean’s remote or home interface, the
method is not delegated to the bean instance. The client’s
invocation of the method simply invalidates the stub and releases the
EJB object: it notifies the container that the client no longer needs
the bean. The container itself invokes the
ejbRemove()
method on the stateless instance, but
only at the end of the instance’s life cycle. Again, this is
different from both stateful session beans and entity beans, which
suffer more destructive consequences when the client invokes a remove
method. During the ejbRemove()
method, the
SessionContext
and access to the JNDI ENC are
still available to the bean instance. Following the execution of the
ejbRemove()
method, the bean is dereferenced
and
eventually
garbage
collected.
[41] Some vendors do not pool stateless instances, but may instead create and destroy instances with each method invocation. This is an implementation-specific decision that shouldn’t impact the specified life cycle of the stateless bean instance.
[42] The duration of a stateless bean instance’s life is assumed to be very long. However, some EJB servers may actually destroy and create instances with every method invocation, making this strategy less attractive. Consult your vendor’s documentation for details on how your EJB server handles stateless instances.