EJB Core
The annotations described in this section are at the heart of EJBs. Just like other Java annotations, these are just pieces of metadata with which you decorate your POJO (Plain Old Java Objects) classes. But their real power is harnessed by the EJB container, which automatically lines up services for your components based on the type of EJB represented by the annotation.
Exploration of these implicit services provided by the EJB runtime and their corresponding annotation is what this book is all about - so you'll read more about these features as you progress. Some of these services include thread safety, concurrency, pooling, transactions, scheduling etc.
Some of the benefits of the annotation driven EJB components are
Clearly distinguishes different EJBs and the bean developer
can make an appropriate choice depending upon the required
business scenario.
Provides a simplified programming model based around POJOs, on top of which features are applied in a declarative fashion using
annotations and the heavy lifting is delegated to the container
Promotes ease-of-use through Convention Over Configuration approach in (common throughout the Java
EE platform) - enables sensible defaults which can be further
refined by annotations or XML deployment descriptors
Without further ado, let's dive in....
@Stateless
@Stateless
It was EJB 3.0 (part of the Java EE 5 specification), which initiated its revival as a lightweight, POJO based programming tool and the @Stateless
annotation was at the centre of it all.
It is just a simple annotation (metadata) which instructs the container to treat a class/interface as a Session Bean whose instances can be pooled. Apart from pooling, there are a host of generic services which a Stateless EJB is eligible for e.g. transactions, thread safety (to name a few)
What's critical to understand is that every time a method on the bean is invoked, a different (pooled) instance is chosen by the container (at random). Hence it goes without saying that, one should not store any state within the bean using instance variables. This is because there is no guarantee as to whether or not the bean which was commissioned to your application for executing the current request will be chosen for the subsequent invocations as well. This is the idea behind the name Stateless: all instances of a Stateless session bean are equivalent
Being unable to store state is not necessarily bad. It actually results in important characteristics such as
Scalability - The container can be tuned to pool instances of your EJBs (more on this later). This is only restricted by the amount of resources (memory and processing capacity) on the physical machinehosting the server.
Thread safety by default - No two threads can ever act on the same instance of the bean, since the container always spins up a new bean instance with each new request.
@Stateful
@Stateful
This annotation defines a session bean whose instances can hold state specific to a client and remain attached to the very same client throughout its life cycle. The container also renders other implicit services like thread safety, transactions etc.
Other key characteristics of Stateful beans
Passivation - Stateful session beans are capable of persisting their state to disk and de-serializing it from the passivated state, back into memory. This can be controlled using the @PrePassivate
and @PostActivate
annotations [discussed later]
From EJB 3.2 onwards, one can also configure a Stateful bean to not get passivated at all.
Removal hooks - A Stateless bean does not provide explicit call back/hook (annotation) which can control its eviction/removal - it's entirely managed by the EJB runtime. In the case of Stateful beans, the bean developer can provide a method annotated with @Remove
which and the trigger bean [discussed later]
JPA Extended Persistence scope - A JPA Entity Manager injected within a Stateful can be configured to leverage Extended Persistence scope which ensures that the JPA entities handled by the Entity Manager remain managed throughout the lifecycle of the EJB i.e. they are not limited to transaction boundaries as is the case with entity managers associates with Stateless EJBs
@Singleton
@Singleton
Think of @Singleton
as a shortcut for producing an implementation of the Singleton pattern (which is often hard to get right). Just a single annotation is enough to ensure that
The container creates a single instance of your bean (scoped to
your container JVM of course)
The container provides implicit thread safety by default
Singleton beans thread safety
A Singleton EJB is a lone warrior. Because of this trait, its is important to configure them appropriately in terms of their concurrency characteristics.
As far as thread safety configuration is concerned, Singleton beans support sensible defaults
Container managed concurrency
Explicit write lock on each of the methods.
Some of the common use cases for using Singleton beans are bootstrapping global configuration, implementing custom caches, starting services on application loading etc.
The associated annotations such as
@Startup
,@DependsOn
,@Lock
and@ConcurrencyType
have been explained in detail later.
@MessageDriven
@MessageDriven
This annotation is used to define a Message Driven Bean (a.k.a MDB). The @ActivationConfigProperty
annotation works hand in hand with @MessageDriven
and helps fine tune its usage [discussed later]
Why MDBs ?
Message Driven beans are generally used in conjunction with JMS (Java Message Service) where JMS acts as a messaging provider/router. Sender (a JMS message producer) uses the JMS API to send messages to JMS specific destinations (queues/topics) and the MDB in turn is tuned to listen to these destinations.
In general, Message Driven Beans provide the following benefits
Ability to consume and process messages in an asynchronous manner
The message sender does not directly interact with a MDB. A MDB is
invoked by the EJB container in response to a message sent to the
component/destination which the MDB is listening to.
Sequence of events
The sender sends the message and it's associated thread returns (frees up) as soon as the message sending process (i.e. the method call) completes
The message consumption and business logic execution is carried out
by the MDB in background by a completely different thread (managed by the EJB container)
Completely decouples the sender and receiver - the sender just knows where to send the message. It's not aware of the specifics of the MDB. Similarly, all the MDB knows about is the message it is supposed to process
Reilability - It offers various degrees of reliability by providing facilities for persistence and acknowledgement of messages which in turn ensures guaranteed message delivery with once-and-only-once semantics.
M for MDB, M for myth ...
MDBs are not part of the JMS specification or coupled with JMS by any means. This is a misconception. Just like Stateless session beans, MDBs are pooled components which can process messages in an asynchronous fashion and can listen to any end point (including a JMS queue or destination) for which there is a compliant JCA resource adapter. In fact, this has been the case since EJB 2.1 and is made possible by the JCA (Java Connector Architecture) specification.
How does JCA enable the concept of Generic MDBs ?
JCA (Java Connector Architecture) defines MDB specific features
Just like in case of a JMS based MDB, a JCA based MDB also needs to
implement an interface and define activation properties (both are
specific to the JCA Resource Adapter implementation)
The external system sends a message which the Resource Adapter
accepts via its implementation of the inbound JCA contract and this
message is relayed to an internal endpoint (this is again specific
to the JCA adapter implementation)
The MDB registered to this endpoint kicks in, and executes the
business logic
What's next ?
The next chapter will dwell into the details of how the EJB container manages the lifecycle of different instances of stateless, stateful, singleton and message driven EJBs.
Last updated