Spring容器的事件监听机制

990 阅读2分钟

这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

前言

Spring的ApplicationContext容器内部中的所有事件类型均继承自 org.springframework.context.AppliationEvent,容器中的所有监听器都实现 org.springframework.context.ApplicationListener接口,并且以bean的形式注册在容器中。一旦在容器内发布ApplicationEvent及其子类型的事件,注册到容器的ApplicationListener就会对这些事件进行处理。

Spring容器内的事件监听机制.png

上面是Spring提供的标准的监听事件。

通过 ApplicationEvent 类和 ApplicationListener 接口来提供在 ApplicationContext 中处理事件。如果一个 bean 实现 ApplicationListener,那么每次 ApplicationEvent 被发布到 ApplicationContext 上,那个 bean 会被通知。

用Spring实现观察者模式

1. 创建监听事件

public class MyEvent extends ApplicationEvent {

    private Long taskId;

    // 创建事件,参数通过构造方法传入
    public MyEvent(Object source, Long taskId) {
        super(source);
        this.taskId = taskId;
    }

    public Long getTaskId() {
        return taskId;
    }
}

2. 事件监听

@Component
@Slf4j
public class MyListener implements ApplicationListener<MyEvent> {

    // 创建一个事件监听
    @Override
    public void onApplicationEvent(MyEvent event) {
        log.info("MyEvent event taskId:{}", event.getTaskId());
    }
}

3. 事件发布

@Component
@Slf4j
public class MyEventPublisher implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher applicationEventPublisher;
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {

        this.applicationEventPublisher = applicationEventPublisher;
    }

    // 比如某个事件处理完成,发布一个任务处理事件做后续处理
    public void publishEvent(Long taskId) {
        log.info("发布事件, 任务ID:{} ", taskId);
        applicationEventPublisher.publishEvent(new MyEvent(this, taskId));

    }
}

4. 测试案例

@SpringBootTest
class SpringActuatorDemoApplicationTests {

    @Resource
    private MyEventPublisher myEventPublisher;

    @Test
    void contextLoads() {
        myEventPublisher.publishEvent(10L);
    }

}

image.png

最后

Spring 源码框架学习主要是学习他的一些设计模式还有架构的思想运用到自己的项目中, 比如你在做一些基础中间件项目的时候就需要考虑到Spring提供的一系列扩展点,Spring框架的生命周期,我们定义的Bean在什么时候加载最合适。如何保证加载配置的正确性等等。