是否可以使Spring ApplicationListener监听两种或更多类型的事件?

我有两种不同类型的事件,我希望我的class级能够听取并相应地处理(以不同的方式)。

我试过: public class ListenerClass implements ApplicationListener, ApplicationListener

这给了我一个错误,你不能用不同的参数两次实现相同的接口。

如果没有实现ApplicationEvent的侦听器(或Foo和Bar将实现的一些其他常见接口)并使用instanceof来确定要采用的路径,我还有其他选择吗?

谢谢!

请参阅本答案末尾的Spring 4.2更新!

spring<4.2

并不是的。

您可以为参数使用公共超类(例如ApplicationEvent)或Foo和Bar实现的公共接口,然后您必须自己使用它。

 public class ListenerClass implements ApplicationListener { ... if(event instanceOf Foo || event instance of Bar) { } } 

另一种方法是使用两个应用程序监听器

 public class ListenerClass { void onFoo(Foo foo){} void onBar(Bar bar){} static class FooListener implements ApplicationListener { ListenerClass listerner; .... public void onApplicationEvent(Foo foo) { listener.onFoo(foo); } } static class BarListener implements ApplicationListener { ListenerClass listerner; .... public void onApplicationEvent(Bar bar) { listener.onBar(bar); } } } 

重要提示:所有3个实例都必须是spring beans!


当然,您可以自己实现这些function。 您至少有两个不同的选择,基于spring事件调度程序框架进行创建或完全分离。 对于第二个选择,看看CDI-Event Mechanim,可能会搜索一些弹簧端口。

几年前我已经实现了自己的第一选择(我想在2007/2008)。 我负责监督所有事件的事件调度员。 它是通过XML文件配置的。 这个xml文件包含“引用”! 对于应该调度的每个事件,bean中的方法 – 这些方法将由reflection调用。 因此,可以使用强类型事件处理程序方法(这是该方法的目标),但也可以在一个类中使用多个处理程序方法。 现在我会跳过xml文件并使用Annotations和Bean-Post-Processor


Spring 4.2更新

Spring 4.2将有一个改进的事件监听器配置(基于注释),这使得在一个bean中有两个不同的事件监听器方法成为可能。

 @Component public class ListenerClass { @EventListener public void handleFooEvent(Foo fooEvent) {...} @EventListener public void handleBarEvent(Bar barEvent) {...} } 

spring<4.2

访问者模式比instanceofstatic class更优雅。 我认为访问者模式提供了一个非常有用的替代旧Spring的缺点。

 public class ListenerClass implements ApplicationListener, 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); } }