一、ApplicationListener 接口

ApplicationListener:监听容器中发布的事件。事件驱动模型开发;

public interface ApplicationListener<E extends ApplicationEvent>

监听 ApplicationEvent 及其下面的子事件

二、步骤

  1. 写一个监听器(ApplicationListener 实现类)来监听某个事件(ApplicationEvent 及其子类)

  2. 把监听器加入到容器;

  3. 只要容器中有相关事件的发布,我们就能监听到这个事件;

ContextRefreshedEvent:容器刷新完成(所有 bean 都完全创建)会发布这个事件;

ContextClosedEvent:关闭容器会发布这个事件;

  1. 发布一个事件:applicationContext.publishEvent();

三、案例

1、自定义一个监听器实现类

@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent{

    //当容器中发布此事件以后,方法触发
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("收到事件:" + event);
    }

}

2、加入到配置文件中

@ComponentScan(value = {"com.njf.ext""com.njf.bean"})
@Configuration
public class ExtConfig {

    @Bean
    public Blue Blue() {
        return new Blue();
    }
}

3、测试

    @Test
    public void test01() {
        AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(ExtConfig.class);

        System.out.println("IOC容器创建完毕!");

        //发布事件
        ioc.publishEvent(new ApplicationEvent(new String("我发布的事件")) {});

        ioc.close();
    }

测试结果:

四、原理

事件监听器原理:

    ContextRefreshedEvent、IOCTest_Ext$1[source=我发布的时间]、ContextClosedEvent;
    1)、ContextRefreshedEvent事件:
        1)、容器创建对象:refresh();
        2)、finishRefresh(); 容器刷新完成会发布ContextRefreshedEvent事件
        3)、参看下面的:【事件发布流程】
            【事件发布流程】:publishEvent(new ContextRefreshedEvent(this));
              1)、获取事件的多播器(派发器):getApplicationEventMulticaster()
              2)、multicastEvent派发事件:
              3)、获取到所有的ApplicationListener;
                  for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
                  1)、如果有Executor,可以支持使用Executor进行异步派发;
                      Executor executor = getTaskExecutor();
                  2)、否则,同步的方式直接执行 listener 方法;invokeListener(listener, event);
                       拿到 listener 回调 onApplicationEvent 方法;

    2)、自己发布事件;【参照上面的事件发布流程】
    3)、容器关闭会发布ContextClosedEvent;

【事件多播器(派发器)】

    1)、容器创建对象:refresh();
    2)、initApplicationEventMulticaster();初始化ApplicationEventMulticaster;
          1)、先去容器中找有没有id=“applicationEventMulticaster”的组件;
          2)、如果没有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
              并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster;

【容器中有哪些监听器】

    1)、容器创建对象:refresh();
    2)、registerListeners();
        从容器中拿到所有的监听器,把他们注册到applicationEventMulticaster中;
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.classtruefalse);
        //将listener注册到ApplicationEventMulticaster中
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);

五、使用 @EvenListener 实现监听事件

在方法上面使用 @EvenListener 注解,可以获取到监听的事件:

@Service
public class UserService {

    @EventListener(classes={ApplicationEvent.class})
    public void listen(ApplicationEvent event)
{
        System.out.println("UserService。。监听到的事件:"+event);
    }
}

运行结果:

使用 @EventListener 注解实现监听事件

@EventListener

原理:使用 EventListenerMethodProcessor 处理器来解析方法上的 @EventListener;

SmartInitializingSingleton 原理:-> afterSingletonsInstantiated();
1、ioc 容器创建对象并 refresh();
2、finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例 bean;
1)先创建所有的单实例 bean;getBean();
2)获取所有创建好的单实例 bean,判断是否是 SmartInitializingSingleton 类型的;
    如果是就调用 afterSingletonsInstantiated();
posted on 2021-11-16 21:42  格物致知_Tony  阅读(78)  评论(0编辑  收藏  举报