I\'ve got 2 different types of events that I want my class to be able to listen for and process accordingly (and differently).
I tried:
public class Listener
See Spring 4.2 update at the end of this answer!
Spring < 4.2
Not really.
You can use a common super class for the argument (for example ApplicationEvent) or a common interface that Foo and Bar implements then you must fitler it by your self.
public class ListenerClass implements ApplicationListener<ApplicationEvent> {
...
if(event instanceOf Foo || event instance of Bar) {
}
}
The other approach would be using two Application Listeners
public class ListenerClass {
void onFoo(Foo foo){}
void onBar(Bar bar){}
static class FooListener implements ApplicationListener<Foo> {
ListenerClass listerner;
....
public void onApplicationEvent(Foo foo) {
listener.onFoo(foo);
}
}
static class BarListener implements ApplicationListener<Bar> {
ListenerClass listerner;
....
public void onApplicationEvent(Bar bar) {
listener.onBar(bar);
}
}
}
Important: all 3 instances must be spring beans!
Of course you can implement such functionality by your own. You have at least two different choices, make it based on the spring event dispatcher framework or do it completely separated. For the second choice defently have a look a the CDI-Event Mechanim, and may search for some spring ports.
I have implemented the first choice by my self some years (I guess in 2007/2008) ago. I have head a event dispatcher that listend to all events. It was configured though an XML file. This xml files contains "references"! to methods in beans for every event that should been dispatched - this methods would been invoked by reflection. So it was possible to have strong typed event handler methods (that was the aim of that approach) but also to have several handler methods in one class. Nowadays I would skip the xml file and would use Annotations and a Bean-Post-Processor
Spring 4.2 update
Spring 4.2 will have an improved event listener configuration (bases on annotations) that makes it possible to have two different event listener Methods in one bean.
@Component
public class ListenerClass {
@EventListener
public void handleFooEvent(Foo fooEvent) {...}
@EventListener
public void handleBarEvent(Bar barEvent) {...}
}
Spring < 4.2
A little more elegant than instanceof
or static class
is the visitor pattern. I think the visitor pattern provides a very useful alternative to that shortcoming of older Spring.
public class ListenerClass implements ApplicationListener<FooBarBase>, FooBarVisitor {
@Override
public void onApplicationEvent(FooBarBase fooBarBase) {
fooBarBase.accept(this);
}
@Override
public void visitFoo(Foo foo) {
System.out.println("Handling Foo Event...");
}
@Override
public void visitBar(Bar bar) {
System.out.println("Handling Bar Event...");
}
}
public interface FooBarVisitor {
void visitFoo(Foo foo);
void visitBar(Bar bar);
}
public abstract class FooBarBase extends ApplicationEvent {
public FooBarBase(Object source) {
super(source);
}
abstract void accept(FooBarVisitor visitor);
}
public class Bar extends FooBarBase {
public Bar(Object source) {
super(source);
}
@Override
void accept(FooBarVisitor visitor) {
visitor.visitBar(this);
}
}
public class Foo extends FooBarBase {
public Foo(Object source) {
super(source);
}
@Override
void accept(FooBarVisitor visitor) {
visitor.visitFoo(this);
}
}