Spring启动流程解析-10-注册事件监听

一,Spring启动流程概述

Spring的IoC容器在实现控制反转和依赖注入的过程中,可以划分为两个阶段:

  • 容器启动阶段

  • Bean实例化阶段

容器初始化

  1. 加载配置

  2. 分析配置信息

  3. 将Bean信息装配到BeanDefinition

  4. 将Bean信息注册到相应的BeanDefinitionRegistry

  5. 其他后续处理

容器实例化

  1. 根据策略实例化对象

  2. 装配依赖

  3. Bean初始化前处理

  4. 对象初始化

  5. 对象其他处理

  6. 注册回调接口

二,Spring启动流程详解

注册事件监听

protected void registerListeners() {
    // 注册静态指定的监听器
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // 从BeanFactory中获取listener的名称,并注册
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // 发布早期事件
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

事件广播类图

说明

ApplicationEventMulticaster

管理多个监听器并向其发布事件对象的接口

AbstractApplicationEventMulticaster

提供监听器注册/管理功能的抽象实现

SimpleApplicationEventMulticaster

将所有事件多播到所有已注册的监听器,让监听器忽略它们不感兴趣的事件。默认情况下,所有监听器在线程中被调用。

源码解读

public void addApplicationListener(ApplicationListener<?> listener) {
    synchronized (this.retrievalMutex) {
        Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
        // 如果代理的目标监听器也已经注册到多播器,为了避免两次都调用相同的监听器
        // 从多播器移除目标监听器
        if (singletonTarget instanceof ApplicationListener) {
            this.defaultRetriever.applicationListeners.remove(singletonTarget);
        }
        this.defaultRetriever.applicationListeners.add(listener);
        this.retrieverCache.clear();
    }
}

@Override
public void addApplicationListenerBean(String listenerBeanName) {
    synchronized (this.retrievalMutex) {
        this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
        this.retrieverCache.clear();
    }
}

// 获取喝Event匹配的事件类型,不匹配的排除在外
protected Collection<ApplicationListener<?>> getApplicationListeners(
			ApplicationEvent event, ResolvableType eventType) {
    // 获取事件源
    Object source = event.getSource();
    // 获取事件类型
    Class<?> sourceType = (source != null ? source.getClass() : null);
    // 使用事件源和事件类型构造缓存Key
    ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);

    // 在缓存中通过Key查找是否存在缓存
    ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
    if (retriever != null) {
        // 如果缓存中存在,则直接返回
        return retriever.getApplicationListeners();
    }

    // 通过类是否在classLoader或者parent classLoader中来判断类是否是可以缓存的
    if (this.beanClassLoader == null ||
        (ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
         (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
        // 同步缓存
        synchronized (this.retrievalMutex) {
            // 通过Key获取缓存
            retriever = this.retrieverCache.get(cacheKey);
            if (retriever != null) {
                // 缓存不为空,则返回
                return retriever.getApplicationListeners();
            }
            // 构造ListenRetriever
            retriever = new ListenerRetriever(true);
            Collection<ApplicationListener<?>> listeners =
                retrieveApplicationListeners(eventType, sourceType, retriever);
            this.retrieverCache.put(cacheKey, retriever);
            return listeners;
        }
    }
    else {
        // 无ListenerRetriever缓存,不需要同步
        return retrieveApplicationListeners(eventType, sourceType, null);
    }
}

// 检索指定事件和源类型的监听器
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
    ResolvableType eventType, Class<?> sourceType, ListenerRetriever retriever) {

    // List为要返回的监听器
    List<ApplicationListener<?>> allListeners = new ArrayList<ApplicationListener<?>>();

    Set<ApplicationListener<?>> listeners;
    Set<String> listenerBeans;
    synchronized (this.retrievalMutex) {
        // 使用成员变量defaultRetriever初始化listeners
        listeners = new LinkedHashSet<ApplicationListener<?>>(this.defaultRetriever.applicationListeners);
        // 使用成员变量defaultRetriever初始化listenerBeans
        listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);
    }
    for (ApplicationListener<?> listener : listeners) {
        // 确定监听器是否支持指定的事件
        if (supportsEvent(listener, eventType, sourceType)) {
            if (retriever != null) {
                // 有缓存的情况(有传参决定)
                retriever.applicationListeners.add(listener);
            }
            allListeners.add(listener);
        }
    }
    if (!listenerBeans.isEmpty()) {
        BeanFactory beanFactory = getBeanFactory();
        for (String listenerBeanName : listenerBeans) {
            try {
                // BeanFactory中获取Class
                Class<?> listenerType = beanFactory.getType(listenerBeanName);
                
                if (listenerType == null || supportsEvent(listenerType, eventType)) {
                    // 从BeanFactory中获取listener
                    ApplicationListener<?> listener =
                        beanFactory.getBean(listenerBeanName, ApplicationListener.class);
                    // allListeners中不包含该监听器,并确定监听器是否支持指定的事件
                    if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
                        if (retriever != null) {
                            // 有缓存的情况(有传参决定)
                            retriever.applicationListenerBeans.add(listenerBeanName);
                        }
                        allListeners.add(listener);
                    }
                }
            }
            catch (NoSuchBeanDefinitionException ex) {
                // Singleton listener instance (without backing bean definition) disappeared -
                // probably in the middle of the destruction phase
            }
        }
    }
    // 对Listener进行排序
    AnnotationAwareOrderComparator.sort(allListeners);
    return allListeners;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值