Java EE6 Events, a lightweight alternative to JMS
Join the DZone community and get the full member experience.
Join For FreeA few weeks ago I attended a bejug meeting about Java EE 6, Building next generation enterprise applications.
Having read much about it, I did not expect to see much shocking hidden
features. But there was one part of the demo I really found impressive.
Due to its loose coupling, Enterprise possibilities and simplicity. The
feature I’m going to talk about today is the event mechanism that is in
java EE 6.
The general idea is to fire an event and let an eventlistener pick it
up. I have created this example that is totally useless, but it
simplicity helps me to focus on the important stuff. I’m going to fire a
LogEvent from my backing action, that will log to the java.util.Logger.
The first thing I need is to create a pojo that contains my log message and my LogLevel.
public class LogMessage implements Serializable { private final String message; private final Level level; LogMessage(String message, Level level) { this.message = message; this.level = level; } public String getMessage() { return message; } public Level getLevel() { return level; } }
easy peasy.
Now that I have my data wrapper, I need something to fire the event and
something to pick it up. The first thing I create is my method where I
fire the event.
Due to CDI I can inject an event.
@Inject Event<LogMessage> event;
So we just need to fire it.
event.fire(new LogMessage("Log it baby!", Level.INFO));
Now the event is fired, If no one is registerd to pick it up, it disappears into oblivion, thus we create a listener. The listeners needs a method that has one parameter, the generic type that is given to the previous event. LogMessage.
public class LogListener { private static final Logger LOGGER = Logger.getAnonymousLogger(); public void process(@Observes LogMessage message){ LOGGER.log(message.getLevel(), message.getMessage()); } }
The @Observes annotation listens to all events with a LogMessage. When the event is fired, this method will be triggered.
This is a very nice way to create a loosely coupled application, you can
separate heavy operations or encapsulate less essential operations in
these event listeners.
All of this all happens synchronously. When we want to replace the log
statement with a slow database call to a logging table, we could make
our operation heavier than it should be. What I’m looking for is to
create an asynchronous call.
As long as we support EJB, we can transform our Listener to an EJB by adding the @Stateless
annotation on top of it. Now it’s a statless enterprise bean. This
changes nothing to our sync/async problem, but EJB 3.1 support async
operations. So if we also add the @Asynchronous annotation on top of it. It will asynchronously execute our logging statement.
@Stateless @Asynchronous public class LogListener { private static final Logger LOGGER = Logger.getAnonymousLogger(); public void process(@Observes LogMessage message){ LOGGER.log(message.getLevel(), message.getMessage()); } }
If we would want to combine the database logging and the console logging, we can just create multiple methods that listen to the same event.
This is a great way to create a lightweight application with a very
flexible components. The alternative solution to this problem is to use
JMS, but you don’t want a heavyweight configuration for this kind of
loosely coupling.
Java EE has worked hard to get rid of the stigma of being heavyweight, I think they are getting there
From http://styledideas.be/blog/2011/05/22/java-ee6-events-a-lightweight-alternative-to-jms/
Opinions expressed by DZone contributors are their own.
Comments