SpringEvent

Spring事件机制

Spring通过事件机制来实现对象间的解耦和通信。它允许应用程序中的各个组件通过发布和监听事件来进行交互。低耦合、无侵入。

1.定义事件

定义事件可以通过继承 ApplicationEvent 类来实现,例如:

public class MsgSendEvent extends ApplicationEvent {
    public MsgSendEvent(Object source) {
        super(source);
    }
}

2.创建事件监听器

创建事件监听器有两种方式,一种是通过实现ApplicationListener接口来实现,另一种则是通过注解@EventListener来实现。

实现ApplicationListener接口方式

创建一个事件监听器,该监听器必须实现 ApplicationListener 接口,并重写 onApplicationEvent 方法来处理事件。例如:

@Slf4j
@Component
public class MsgSendListener implements ApplicationListener<MsgSendEvent> {
    @Override
    public void onApplicationEvent(MsgSendEvent msgSendEvent) {
        log.info("建听到消息发送事件 消息内容:{}",JSON.toJSONString(msgSendEvent.getSource()));
    }
}

通过 @EventListener 注解方式

在监听器方法上添加 @EventListener 注解,并将事件类作为参数传入。例如:

@Slf4j
@Component
public class MsgSendListener {
    @EventListener
    public void start(MsgSendEvent msgSendEvent) {
        log.info("建听到消息发送事件 消息内容:{}",JSON.toJSONString(msgSendEvent.getSource()));
    }
}

3.触发事件

    @Resource
    private ApplicationContext applicationContext;
    @GetMapping("/test")
    public String notice(String msg){
        applicationContext.publishEvent(new MsgSendEvent(msg));
        return "OK";
    }

4.Spring内置事件

ContextRefreshedEvent

ContextRefreshedEvent是在ConfigurableApplicationContextrefresh()方法完成后发布的。refresh()是Spring核心方法,用于启动Spring容器。当容器启动完成时,会通过finishRefresh()发布ContextRefreshedEvent事件,通知容器刷新完成。

// ConfigurableApplicationContext.java
public void refresh() throws BeansException, IllegalStateException {
    try {
        // ...省略部分非关键代码
        //完成普通单例Bean的实例化(非延迟的)
        this.finishBeanFactoryInitialization(beanFactory);

        // 初始化声明周期处理器,并发出对应的时间通知
        this.finishRefresh();
    }
}

protected void finishRefresh() {
    // ...省略部分非核心代码
    // 发布上下文已经刷新完成的事件
    this.publishEvent(new ContextRefreshedEvent(this));
}

ContextStartedEvent

ConfigurableApplicationContextstart()执行完成时,会发出ContextStartedEvent事件。 ContextRefreshedEvent事件的触发是所有的单例bean创建完成后发布,此时实现了Lifecycle接口的bean还没有回调start(),当这些start()被调用后,才会发布ContextStartedEvent事件。

ContextClosedEvent

ConfigurableApplicationContextclose()执行完成时,会发出ContextClosedEvent事件。此时IOC容器已经关闭,但尚未销毁所有的bean。

ContextStoppedEvent

ConfigurableApplicationContextstop()执行完成时,会发出ContextStoppedEvent事件。

参考