我有两种不同类型的事件,我希望我的班级能够相应地(以不同的方式)收听和处理。
我试过了:
public class ListenerClass implements ApplicationListener<Foo>, ApplicationListener<Bar>
这给了我一个错误,你不能用不同的参数两次实现相同的接口。
如果没有实现ApplicationEvent的侦听器(或Foo和Bar将实现的一些其他常见接口)并使用instanceof
来确定要采用的路径,我还有其他选择吗?
谢谢!
答案 0 :(得分:33)
请参阅本答复末尾的Spring 4.2更新!
春天&lt; 4.2 强>
不是。
您可以为参数使用公共超类(例如ApplicationEvent)或Foo和Bar实现的公共接口,然后您必须自己使用它。
public class ListenerClass implements ApplicationListener<ApplicationEvent> {
...
if(event instanceOf Foo || event instance of Bar) {
}
}
另一种方法是使用两个应用程序监听器
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);
}
}
}
重要提示:所有3个实例都必须是spring beans!
当然,您可以自己实现此类功能。您至少有两个不同的选择,基于spring事件调度程序框架进行创建或完全分离。对于第二个选择,看看CDI-Event Mechanim,可能会搜索一些弹簧端口。
我已经实现了自己的第一选择(我想在2007/2008)。我负责监督所有事件的事件调度员。它是通过XML文件配置的。这个xml文件包含“引用”!对于应该调度的每个事件,bean中的方法 - 这些方法将由反射调用。因此,可以使用强类型事件处理程序方法(这是该方法的目标),但也可以在一个类中使用多个处理程序方法。现在我会跳过xml文件并使用Annotations和Bean-Post-Processor
Spring 4.2 更新
Spring 4.2 will have an improved event listener配置(基于注释),可以在一个bean中使用两个不同的事件侦听器方法。
@Component
public class ListenerClass {
@EventListener
public void handleFooEvent(Foo fooEvent) {...}
@EventListener
public void handleBarEvent(Bar barEvent) {...}
}
答案 1 :(得分:3)
春天&lt; 4.2 强>
比instanceof
或static class
更优雅的是访客模式。我认为访客模式提供了一个非常有用的替代方案,可以解决老春的缺点。
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);
}
}