内置事件

Spring中的事件是一个ApplicationEvent类的子类,由实现ApplicationEventPublisherAware接口的类发送,实现ApplicationListener接口的类监听。

ApplicationContext 事件

Spring中已经定义了一组内置事件,这些事件由ApplicationContext容器发出。

例如,ContextStartedEventApplicationContext启动时发送,ContextStoppedEventApplicationContext停止时发送。

实现ApplicationListener的类可以监听事件。

Spring的事件是同步的(单线程的),会被阻塞。

监听ApplicationContext事件

要监听ApplicationContext事件,监听类应该实现ApplicationListener接口并重写onApplicationEvent()方法。

ContextStartEventHandler.java

  1. import org.springframework.context.ApplicationListener;
  2. import org.springframework.context.event.ContextStartedEvent;
  3. public class ContextStartEventHandler implements ApplicationListener<ContextStartedEvent>{
  4. @Override
  5. public void onApplicationEvent(ContextStartedEvent event) {
  6. System.out.println("ApplicationContext 启动... ");
  7. }
  8. }

Test.java

  1. import org.springframework.context.ApplicationContext;
  2. import org.springframework.context.ConfigurableApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class Test {
  5. public static void main(String[] args) {
  6. // ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
  7. // fire the start event.
  8. // ((ConfigurableApplicationContext) context).start();
  9. ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
  10. // fire the start event.
  11. context.start();
  12. // ...
  13. }
  14. }

在XML配置文件中,将该类为声明为Bean,以便Spring容器加载该Bean,并向其传送事件。

  1. <bean id="contextStartEventHandler" class="ContextStartEventHandler"></bean>

自定义事件

除了内置事件,Spring中也可以使用自定义事件。

怎样使用自定义事件:

  • 创建事件类 – 扩展ApplicationEvent类,创建事件类。
  • 创建发送类 – 发送类获取ApplicationEventPublisher实例发送事件。
  • 创建监听类 – 实现ApplicationListener接口,创建监听类。

事件类

事件类用于存储事件数据。下面创建一个简单的事件类。

CustomEvent.java

  1. import org.springframework.context.ApplicationEvent;
  2. public class CustomEvent extends ApplicationEvent {
  3. public CustomEvent(Object source, String message) {
  4. super(source);
  5. }
  6. public String toString() {
  7. return "我是自定义事件";
  8. }
  9. }

发送类

发送类创建事件对象并发送。

要发送事件,这里介绍2种方法:

  1. 使用@autowired注解注入ApplicationEventPublisher实例。

CustomEventPublisher.java

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.context.ApplicationEventPublisher;
  3. public class CustomEventPublisher {
  4. @Autowired
  5. private ApplicationEventPublisher publisher;
  6. public void publish() {
  7. CustomEvent event = new CustomEvent(this);
  8. publisher.publishEvent(event);
  9. }
  10. }
  1. 发送类实现ApplicationEventPublisherAware接口,获取ApplicationEventPublisher实例。

CustomEventPublisher.java

  1. import org.springframework.context.ApplicationEventPublisher;
  2. import org.springframework.context.ApplicationEventPublisherAware;
  3. public class CustomEventPublisher implements ApplicationEventPublisherAware {
  4. private ApplicationEventPublisher publisher;
  5. // 必须重写这个方法获取ApplicationEventPublisher
  6. public void setApplicationEventPublisher (ApplicationEventPublisher publisher){
  7. this.publisher = publisher;
  8. }
  9. public void publish() {
  10. CustomEvent event = new CustomEvent(this);
  11. publisher.publishEvent(event);
  12. }
  13. }

如果发送类实现了ApplicationEventPublisherAware接口,发送类必须声明为bean,Spring容器将其标识为事件发送者。

  1. <bean id="customEventPublisher" class="CustomEventPublisher"/>

监听类

监听类监听事件。监听类必须实现ApplicationListener接口,并且被定义为Bean以便Spring容器可以加载它。

beans.xml

  1. <bean id="customEventHandler" class="CustomEventHandler"/>

CustomEventHandler.java

  1. import org.springframework.context.ApplicationListener;
  2. public class CustomEventHandler implements ApplicationListener<CustomEvent> {
  3. public void onApplicationEvent(CustomEvent event) {
  4. System.out.println("收到事件:" + event.toString());
  5. }
  6. }

运行

测试自定义事件。

Test.java

  1. import org.springframework.context.ApplicationContext;
  2. import org.springframework.context.ConfigurableApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class Test {
  5. public static void main(String[] args) {
  6. ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
  7. CustomEventPublisher publisher = (CustomEventPublisher) context.getBean("customEventPublisher");
  8. publisher.publish();
  9. }
  10. }