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: the Does Not Exist state and the 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.[27] Figure 7.1 illustrates the states and transitions that a stateless session bean instance goes through in its lifetime.
When a bean instance 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 will probably 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.
Bean classes, entity and session alike, must never define constructors. Take care of initialization needs within ejbCreate()
and other callback methods available through the bean class’s EnterpriseBean
interface (EntityBean
or SessionBean
). The container instantiates instances of the bean class using Class.newInstance()
, which requires a no-argument constructor.
Although the life cycle of a bean instance is defined by the specification, the actual implementation by EJB vendors need only support the specified life cycle as perceived by the bean class and the client. For this reason, a bean developer must only depend on behavior described by the specification. The specification does not describe the behavior of Java language constructors; it only describes the behavior of the create and callback methods in the 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.[28]
Finally, the no-argument
ejbCreate()
method is invoked on the bean
instance. Remember that a stateless session bean only has 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. This is significantly different from
both entity beans and stateful session beans.
Stateless session beans are not
subject to activation, so they can maintain open connections to
resources for their entire life cycle.[29] The
ejbRemove()
method should close any open
resources before the stateless session bean is evicted from memory at
the end of its life cycle. 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 6. In the entity instance pool, a bean instance might be swapped in to service an EJB object for several method invocations. Stateless session instances are only dedicated to an EJB object for the duration of the method.
Although vendors can choose different strategies to support stateless
session beans, it’s likely that vendors will use an
instance-swapping strategy similar to that used for entity beans (the strategy utilized by
entity beans is described in Chapter 6). 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 that needs to preserved.
(Stateful session beans do depend on activation,
as we’ll see later.)
Clients that need a remote reference to a stateless session bean
begin by invoking the create()
method on the
bean’s EJB home:
// EJB 1.0: Use native cast Object ref = jndiConnection.lookup("ProcessPaymentHome"); ProcessPaymentHome home = (ProcessPaymentHome) PortableRemoteObject.narrow(ref,ProcessPaymentHome.class); ProcessPayment 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. The
ejbCreate()
method of a stateless session bean is
only invoked once in the life cycle of an instance—when it is
transitioning from the Does Not Exist state to the Method-Ready Pool.
It isn’t reinvoked every time a client requests a remote
reference to the bean.
Bean instances leave the
Method-Ready Pool for the Does Not Exist state when the server no
longer needs the instance. This occurs 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, like closing
open resources. The ejbRemove()
method is only
invoked 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,
it is not delegated to the bean instance. The client’s
invocations of this 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
very 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 JNDI ENC for EJB 1.1) is still
available to the bean instance. Following the execution of the
ejbRemove()
method, the bean is
dereferenced and eventually garbage collected.
[27] 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.
[28] The EJB 1.0 specification is not clear on
whether an EJBContext
should be stored in a
transient or nontransient field in the bean instance. The recommended
approach is to use nontransient, but some vendors will preserve an
EJBContext
reference’s binding to the
instance only if it is set as a transient field. Consult your vendor
for its implementation-specific requirements. EJB 1.1 explicitly
states that the EJBContext
must
not be referenced in a transient field.
[29] 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.