在Spring中的多个事件上使用@EventListener注释

时间:2017-08-25 15:15:17

标签: java spring spring-mvc events event-listener

这似乎是一个非常直截了当的问题,但我似乎无法在任何地方找到答案。

在Spring中,我可以使用@EventListener注释为事件创建一个侦听器,如下所示:

@Component
public class MyListener {

    @EventListener
    public void handleEvent(ContextRefreshedEvent event) {
        ...
    }
}

但是,如果我需要相同的方法来收听多个事件并根据发生的事件采取不同的行动呢?

直观地说,我在想类似的事情:

    @Component
    public class MyListener {

        @EventListener
        public void handleEvents(ContextRefreshedEvent event, ContextStopped event) {
             String event;
             if(event instanceof ContextRefreshedEvent)
                  event = "Refreshed";
             if(event instanceof ContextStoppedEvent)
                  event = "Stopped";
        }
    }

EventListener注释监听多个事件的正确方法是什么?同一方法如何根据发生的实际事件进行区分?

非常感谢。

4 个答案:

答案 0 :(得分:8)

创建一个侦听多个事件的事件监听器名义上很容易:

@EventListener({EventA.class, EventB.class})
public doSomething() {
   ...
}

但很明显,这种方法无法让您访问基础事件。基于EventListener的javadoc,似乎无法按照您的建议行事

  

如果带注释的方法支持单个事件类型,则该方法可以   声明一个反映要侦听的事件类型的参数。   如果带注释的方法支持多个事件类型,则此注释   可以使用类来引用一个或多个支持的事件类型   属性。有关更多详细信息,请参阅classes()javadoc。

     

...

     

如果(   classes)属性使用单个值指定,带注释   方法可以可选地接受单个参数。但是,如果这样   属性是用多个值指定的,带注释的方法必须   不要声明任何参数。

因此,似乎没有任何机制可以使用多个事件并根据这些事件的主体采取不同的操作。我建议这不应该是必要的,你可以随时注册特定于事件的@EventListener方法,然后让它们调用共享方法来执行任何常见功能。

来源:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/event/EventListener.html

答案 1 :(得分:4)

从Spring 4.2开始,您可以在方法声明中使用子类来处理扩展此子类的所有事件:

@EventListener
public void handleEvent(ApplicationEvent event) {
  // listen all descendants of the ApplicationEvent
}

您还可以使用annotion的属性缩小事件列表:

@EventListener({ContextRefreshedEvent.class, ApplicationReadyEvent.class})
public void handleEvent(Object event) {
  // listen only ContextRefreshedEvent and ApplicationReadyEvent
}

答案 2 :(得分:2)

为什么不做这样的事情。

SpringFramework 4.2,您可以在不延长ApplicationEvent的情况下发布活动。

当你回答时,你想要主要听自定义事件。你可以做这样的事情。

创建一个名为BaseEvent的基类。

public class BaseEvent {

  private String type;

  public BaseEvent() {}

  public String getType() {
    return type;
  }

  public void setType(String type) {
    this.type = type;
  }
}

每当您想要发布自定义Event时,请将其视为基类。

现在让我们创建两个名为Example1EventExample2Event的自定义事件。

Example1Event班级

public class Example1Event extends BaseEvent {

  private String message;

  public Example1Event() {}

  public String getMessage() {
    return message;
  }

  public void setMessage(String message) {
    this.message = message;
  }
}

Example2Event班级

public class Example2Event extends BaseEvent {

  private String message;

  public Example2Event() {}

  public String getMessage() {
    return message;
  }

  public void setMessage(String message) {
    this.message = message;
  }
}

您的EventListener看起来像这样。

public class EventReceiver {

  public EventReceiver() {}

  @EventListener
  public void receiveEvent(BaseEvent event) {
    String eventType = event.getType();
    if (eventType.equals("example1")) {
      Example1Event example1Event = (Example1Event) event;
      System.out.println(example1Event.getMessage());
    } else if (eventType.equals("example2")) {
      Example2Event example2Event = (Example2Event) event;
      System.out.println(example2Event.getMessage());
    }
  }
}

这适用于您想要做的事情。

答案 3 :(得分:0)

每个单独的事件可以有多个EventListener。