Skip to content

jvassev/easyevents

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 

Repository files navigation

This is a simple Spring add-on that simplifies working with custom events and also Spring 
ApplicationEvents.

It is inspired by CDI that I read about in this blog
http://www.reverttoconsole.com/blog/jee6/understanding-jsr299-contexts-and-dependency-injection-explained/
I find using a simple annotation easier than defining a Listener interface and an Observable that
has and (add|remove)Listener methods.

So here is how it works
You need a simple (a)synchronous notifications across your beans. For example we'd like to monitor Deployment events.
For every Deployment you'd like to send an email asynchronously.

The first thing that comes to mind is this:

public interface DeploymentListener {
  void onDeployment(Deployment deployment);
}

public interface DeploymentService {
  void addDeploymentListener(DeploymentListener listener);
  void removeDeploymentListener(DeploymentListener listener);
  void fireDeploymentEvent(Deployment deployment);
}

public class EmailNotifier implements DeploymentListener {
  void onDeployment(Deployment deployment) {
    // send mail
  }
  
  //even more code omitted: adding 'this' to a DeploymentService bean 
}

public class ComplexBean {

  void deploy() {
    // ...
    deploymentService.fireDeploymentEvent(new Deployment());
  }
}

This machinery is not really needed. What's more the code for managing listeners is not listed and is probably buried
in some AbstractDeploymentService class.

Bottom line is it all boils down to sending an event and receiving it. The easyevent package handles listeners in a 
generic way. There are two abstractions:

public interface EventPublisher {
    public void publish(Object event);
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Observer {

}


You'd use a single EventPublisher to publish all kinds of events. You handle the events in a method annotated with @Observer:

public class EmailNotifier implements DeploymentListener {
  
  @Observer
  public void onDeployment(Deployment deployment) {
    // send mail
  }
}



public class MyBean {
  void deploy() {
    // ...
    eventPublisher.publish(new Deployment());
  }
}

But what if also need to send an email on Restart events? Write another family of interfaces?
It's as easy as adding another annotated method:

public class EmailNotifier implements DeploymentListener {
  
  @Observer
  public void onDeployment(Deployment deployment) {
    // send mail
  }
  
  @Observer
  public void onRestart(Restart restart) {
    // send mail
  }
}


All public void, single-argument methods annotated with @Observer are eligible for event-handlers. The name of the method
doesn't matter.

And this is the spring xml you'd need to enable the easyevents:
  <task:executor id="taskExecutor" pool-size="5" />
  
  <bean id="eventPublisher" class="org.springthing.easyevents.DefaultEventPublisher">
    <property name="taskExecutor" ref="taskExecutor"/>
  </bean>
  
  <bean class="org.springthing.easyevents.ObserverAnnotationBeanPostProcessor">
    <property name="eventPublisherImpl" ref="eventPublisher"/>
  </bean>

Setting taskExecutor is optional and allows for executing the handler methods asynchronously. If it is not
set the handlers will be executed in the publisher's thread.


Easyevents is also integrated with spring's ApplicationEvents (http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#context-functionality-events)

If you'd like to handle all RequestHandledEvent events, just annotate a method of on of your beans - just make sure that
it has exactly 1 argument of type RequestHandledEvent

@Observer
public void requestProcessed(RequestHandledEvent event) {
  ...
}

You can also easily publish such event using eventPublisher.publish(new RequestHandledEvent()) yourself!

 

About

Easy events for spring, like in CDI

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages