express interest in one or more classes,
and only receive messages that are of
interest, without knowledge of what, if
any, publishers there are. This pattern
provides greater network scalability and
a more dynamic network topology.”
The key point of publish-subscribe
is its dynamic nature. Listeners and
broadcasters can come and go. There is a
dynamic N:M relation between listeners
and broadcasters; there is no require-
ment for the existence of any. A broad-
caster could send a message without
the existence of any listener. There
could be several listeners without any
broadcaster. The
“message” in the
publish-subscribe
definition does not,
however, have to
be a
javax.jms
.Message. It is bet-
ter to think about
messages as events
or payloads. With
CDI and EJB 3. 1,
you can implement
lean publish-sub-
scribe communica-
tion without JMS.
Java EE 6 (and
CDI, in particu-
lar) comes with a built-in event: the
injectable javax.enterprise.event.Event. It
allows you to fire (distribute) any object
you like to all listeners locally. If there
is no listener, the broadcasted payload
just disappears. To send a message you
only have to inject the Event class and
decide which kind of payload you would
@Stateless
public class MessageBroadcaster {
@Inject
Event<String> event;
public void broadcast(String message){
}
}
COMMUNITY
JAVA IN ACTION
See all listings as text
Then, annotate the corresponding
parameter:
Although a JMS
publish-subscribe
implementation
is more powerful
and flexible, it
also requires that
significantly more
code be written.
like to distribute. Listing 6 shows a CDI
String broadcaster.
The message is sent with a single
invocation of the fire method. CDI events
are transaction-aware and EJB 3. 1 beans
are transactional by convention. Because
there is no configuration (annotation or
XML), the broadcast method is going to
be executed within a transaction.
The listener is required to implement
only a void method with a single parameter annotated with the @Observes
annotation. Listing 7 shows a CDI String
listener. The type of the parameter
denoted with the @Observes annotation
must match the type of the fired payload. Only then does the message get
delivered; otherwise, it just disappears.
Unlike JMS, with CDI you can easily
observe successful and unsuccessful
transactions with a single listener at
the same time. You only need to set the
during element of the @Observes annotation. Listing 8 shows an example of how
to listen to commits and rollbacks at the
same time. The message gets delivered
only in the specified transaction phase.
The @Observes(during=) element makes
CDI events particularly useful for the
implementation of batch job monitoring
or audits. You can easily track all successful and failed transactions.
What About Multiple Destinations?
CDI eventing is type-safe. If the “fired”
and “observed” types match, the event
gets delivered; otherwise, it is ignored.
With the current approach, you can
use a type only once. There is no way
to distinguish between important and
tenuous messages. You could, of course,
extend the type of the message by wrap-
ping the string with a custom event
class. Listing 9 shows a custom event
class for event dispatching.
public void onImportantMessage
(@Observes @Importance
( Importance.Degree.HIGH)
String message){}.
@Inject @Importance
( Importance.Degree.HIGH)
Event<String> event;
There is still one deficiency: You need
to inject an Event for every channel with
the given qualifier. Instead of injecting
the Event with different qualifiers multiple times, you can select the Qualifier
on the fly, as shown in Listing 11, which
shows dynamic channel selection. For
the on-the-fly selection of the message
listener, you only have to pass a Qualifier
instance to the select method. The problem is that it is impossible to instantiate
an annotation. Listing 12 shows a helper
class for annotation instantiation.
The class ImportanceSelector in
Listing 12 implements the Importance
annotation and returns its enum value
as well as the annotation type. The
enum Degree is passed as a construc-
ABOUT US