Spring IoC源码学习:finishRefresh 详解

目录

Spring IoC源码学习全系列

前言

正文

代码块1:initApplicationEventMulticaster

代码块2:registerListeners

代码块3:finishRefresh

代码块4:initLifecycleProcessor

代码块5:onRefresh

代码块6:publishEvent

代码块7:multicastEvent

代码块8:invokeListener

自定义监听器实现

总结

相关文章


Spring IoC源码学习全系列

小白也看得懂的 Spring IoC 核心流程介绍

Spring IoC源码学习:总览

Spring IoC源码学习:ApplicationContext 刷新前的配置

Spring IoC源码学习:obtainFreshBeanFactory详解

Spring IoC源码学习:parseDefaultElement详解

Spring IoC源码学习:parseCustomElement详解

Spring IoC源码学习:obtainFreshBeanFactory详解

Spring IoC源码学习:invokeBeanFactoryPostProcessors详解

Spring IoC源码学习:registerBeanPostProcessors详解

Spring IoC源码学习:finishBeanFactoryInitialization详解

Spring IoC源码学习:getBean详解

Spring IoC源码学习:createBean详解(上)

Spring IoC源码学习:createBean详解(下)

Spring IoC源码学习:@Autowire 详解

Spring IoC源码学习:finishRefresh 详解

 

前言

Spring IoC 的核心内容已经介绍完毕,本文将对最后一个方法 finishRefresh 进行介绍。由于存在上下文关系,本文也会对 initApplicationEventMulticaster 方法、registerListeners 方法进行介绍。

 

正文

首先,我们回到 refresh 方法。

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        prepareRefresh();
 
        // Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);
 
        try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);
 
            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);
 
            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);
 
            // Initialize message source for this context.
            initMessageSource();
 
            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();
 
            // Initialize other special beans in specific context subclasses.
            onRefresh();
 
            // Check for listener beans and register them.
            registerListeners();
 
            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);
 
            // Last step: publish corresponding event.
            finishRefresh();
        } catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }
 
            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();
 
            // Reset 'active' flag.
            cancelRefresh(ex);
 
            // Propagate exception to caller.
            throw ex;
        } finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

initApplicationEventMulticaster():初始化应用的事件广播器,见代码块1详解

registerListeners():注册监听器,见代码块2详解

finishRefresh():完成上下文的刷新工作,见代码块3详解

 

代码块1:initApplicationEventMulticaster

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    // 1.判断BeanFactory是否已经存在事件广播器(固定使用beanName=applicationEventMulticaster)
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        // 1.1 如果已经存在,则将该bean赋值给applicationEventMulticaster
        this.applicationEventMulticaster =
                beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    } else {
        // 1.2 如果不存在,则使用SimpleApplicationEventMulticaster
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        // 并将SimpleApplicationEventMulticaster作为默认的事件广播器,注册到BeanFactory中
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                    APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                    "': using default [" + this.applicationEventMulticaster + "]");
        }
    }
}

内容比较简单,就是要初始化应用的事件广播器。通过之前的学习我们知道,在 Spring 中,有一些内部的 bean 会使用固定的 beanName,这边的事件广播器就是这样,固定使用 beanName :applicationEventMulticaster。

具体的,如果当前 BeanFactory 中已经存在 beanName = applicationEventMulticaster 的 bean 实例或者 BeanDefinition,那么就使用该 bean 作为 applicationEventMulticaster。

否则,新建一个默认的事件广播器 SimpleApplicationEventMulticaster 作为 applicationEventMulticaster,并且会注册到 BeanFactory 中。

 

代码块2:registerListeners

protected void registerListeners() {
    // Register statically specified listeners first.
    // 1.通过硬编码调用addApplicationListener方法添加的监听器处理(可以通过自定义ApplicationContextInitializer添加)
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let post-processors apply to them!
    // 2.通过配置文件或注解注入BeanFactory的监听器处理
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // Publish early application events now that we finally have a multicaster...
    // 3.使用事件广播器,发布早期应用程序事件到相应的监听器
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

1.通过硬编码调用 addApplicationListener 方法添加的监听器处理,可以通过自定义 ApplicationContextInitializer 添加,关于自定义 ApplicationContextInitializer 请见 Spring IoC:ApplicationContext 刷新前的配置 中的代码块12

 

代码块3:finishRefresh

protected void finishRefresh() {
    // Initialize lifecycle processor for this context.
    // 1.为此上下文初始化生命周期处理器
    initLifecycleProcessor();

    // Propagate refresh to lifecycle processor first.
    // 2.首先将刷新完毕事件传播到生命周期处理器(触发isAutoStartup方法返回true的SmartLifecycle的start方法)
    getLifecycleProcessor().onRefresh();

    // Publish the final event.
    // 3.推送上下文刷新完毕事件到相应的监听器
    publishEvent(new ContextRefreshedEvent(this));

    // Participate in LiveBeansView MBean, if active.
    LiveBeansView.registerApplicationContext(this);
}

1.为此上下文初始化生命周期处理器,见代码块4详解

2.首先将刷新完毕事件传播到生命周期处理器,见代码块5详解

3.推送上下文刷新完毕事件到相应的监听器,见代码块6详解

 

代码块4:initLifecycleProcessor

protected void initLifecycleProcessor() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    // 1.判断BeanFactory是否已经存在生命周期处理器(固定使用beanName=lifecycleProcessor)
    if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
        // 1.1 如果已经存在,则将该bean赋值给lifecycleProcessor
        this.lifecycleProcessor =
                beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
        }
    } else {
        // 1.2 如果不存在,则使用DefaultLifecycleProcessor
        DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
        defaultProcessor.setBeanFactory(beanFactory);
        this.lifecycleProcessor = defaultProcessor;
        // 并将DefaultLifecycleProcessor作为默认的生命周期处理器,注册到BeanFactory中
        beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate LifecycleProcessor with name '" +
                    LIFECYCLE_PROCESSOR_BEAN_NAME +
                    "': using default [" + this.lifecycleProcessor + "]");
        }
    }
}

初始化生命周期处理器,过程同代码块1类似,优先使用用户自定义的生命周期处理器;如果用户没有自定义,则使用默认的 DefaultLifecycleProcessor。

 

代码块5:onRefresh

@Override
public void onRefresh() {
    startBeans(true);
    this.running = true;
}

private void startBeans(boolean autoStartupOnly) {
    // 1.获取所有的Lifecycle bean
    Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
    // 将Lifecycle bean 按阶段分组,阶段通过实现Phased接口得到
    Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
    // 2.遍历所有Lifecycle bean,按阶段值分组
    for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
        Lifecycle bean = entry.getValue();
        // autoStartupOnly=true代表是ApplicationContext刷新时容器自动启动;autoStartupOnly=false代表是通过显示的调用启动
        // 3.当autoStartupOnly=false,也就是通过显示的调用启动,会触发全部的Lifecycle;
        // 当autoStartupOnly=true,也就是ApplicationContext刷新时容器自动启动,只会触发isAutoStartup方法返回true的SmartLifecycle
        if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
            // 3.1 获取bean的阶段值(如果没有实现Phased接口,则值为0)
            int phase = getPhase(bean);
            // 3.2 拿到存放该阶段值的LifecycleGroup
            LifecycleGroup group = phases.get(phase);
            if (group == null) {
                // 3.3 如果该阶段值的LifecycleGroup为null,则新建一个
                group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                phases.put(phase, group);
            }
            // 3.4 将bean添加到该LifecycleGroup
            group.add(entry.getKey(), bean);
        }
    }
    // 4.如果phases不为空
    if (!phases.isEmpty()) {
        List<Integer> keys = new ArrayList<Integer>(phases.keySet());
        // 4.1 按阶段值进行排序
        Collections.sort(keys);
        // 4.2 按阶段值顺序,调用LifecycleGroup中的所有Lifecycle的start方法
        for (Integer key : keys) {
            phases.get(key).start();
        }
    }
}

这边讲下 autoStartupOnly 这个参数。

autoStartupOnly = true 时,代表这次刷新是 ApplicationContext 刷新时容器自动启动,在这个阶段只会触发 SmartLifecycle,并且要求 SmartLifecycle 的 isAutoStartup() 方法必须返回 true。

而 autoStartupOnly = false,代表这次刷新是通过显示的调用启动,会触发所有的 Lifecycle。

这边还引入了 Phased 接口,这个接口类似于 Ordered 接口,只有一个方法用于返回一个 “阶段值”,范围为 Integer.MIN_VALUE ~ Integer.MAX_VALUE。在启动过程,“阶段值” 小的会被优先调用,而在关闭过程,“阶段值” 大的会被优先调用。

 

代码块6:publishEvent

@Override
public void publishEvent(ApplicationEvent event) {
    publishEvent(event, null);
}

protected void publishEvent(Object event, ResolvableType eventType) {
    Assert.notNull(event, "Event must not be null");
    if (logger.isTraceEnabled()) {
        logger.trace("Publishing event in " + getDisplayName() + ": " + event);
    }

    // Decorate event as an ApplicationEvent if necessary
    // 1.如有必要,将事件装饰为ApplicationEvent
    ApplicationEvent applicationEvent;
    if (event instanceof ApplicationEvent) {
        applicationEvent = (ApplicationEvent) event;
    } else {
        applicationEvent = new PayloadApplicationEvent<Object>(this, event);
        if (eventType == null) {
            eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
        }
    }

    // Multicast right now if possible - or lazily once the multicaster is initialized
    if (this.earlyApplicationEvents != null) {
        this.earlyApplicationEvents.add(applicationEvent);
    } else {
        // 2.使用事件广播器广播事件到相应的监听器
        getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
    }

    // Publish event via parent context as well...
    // 3.同样的,通过parent发布事件......
    if (this.parent != null) {
        if (this.parent instanceof AbstractApplicationContext) {
            ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
        } else {
            this.parent.publishEvent(event);
        }
    }
}

2.使用事件广播器广播事件到相应的监听器,见代码块7详解

 

代码块7:multicastEvent

@Override
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    // 1.getApplicationListeners:返回与给定事件类型匹配的应用监听器集合
    for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        // 2.返回此广播器的当前任务执行程序
        Executor executor = getTaskExecutor();
        if (executor != null) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    // 3.1 executor不为null,则使用executor调用监听器
                    invokeListener(listener, event);
                }
            });
        } else {
            // 3.2 否则,直接调用监听器
            invokeListener(listener, event);
        }
    }
}

3.2 调用监听器,见代码块8详解

 

代码块8:invokeListener

protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
    // 1.返回此广播器的当前错误处理程序
    ErrorHandler errorHandler = getErrorHandler();
    if (errorHandler != null) {
        try {
            // 2.1 如果errorHandler不为null,则使用带错误处理的方式调用给定的监听器
            doInvokeListener(listener, event);
        } catch (Throwable err) {
            errorHandler.handleError(err);
        }
    } else {
        // 2.2 否则,直接调用调用给定的监听器
        doInvokeListener(listener, event);
    }
}

private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    try {
        // 触发监听器的onApplicationEvent方法,参数为给定的事件
        listener.onApplicationEvent(event);
    } catch (ClassCastException ex) {
        String msg = ex.getMessage();
        if (msg == null || msg.startsWith(event.getClass().getName())) {
            // Possibly a lambda-defined listener which we could not resolve the generic event type for
            Log logger = LogFactory.getLog(getClass());
            if (logger.isDebugEnabled()) {
                logger.debug("Non-matching event type for listener: " + listener, ex);
            }
        } else {
            throw ex;
        }
    }
}

 

自定义监听器实现

如果我们想在 Spring IoC 容器构建完毕之后进行一些逻辑,就可以通过监听器来实现。

创建一个自定义监听器,实现 ApplicationListener 接口,监听 ContextRefreshedEvent(上下文刷新完毕事件),并且将该监听器注册到 Spring IoC 容器即可。

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

/**
 * @author joonwhee
 * @date 2019/6/22
 */
@Component
public class MyRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 自己的逻辑处理
    }
}

这样,当 Spring 执行到 finishRefresh 方法时,就会将 ContextRefreshedEvent 事件推送到 MyRefreshedListener 中。

跟 ContextRefreshedEvent 相似的还有:ContextStartedEvent、ContextClosedEvent、ContextStoppedEvent,有兴趣的可以自己看看这几个事件的使用场景。

当然,我们也可以自定义监听事件,只需要继承 ApplicationContextEvent 抽象类即可。

 

总结

本文主要介绍了几个用于扩展使用的功能:

  • ApplicationEventMulticaster:应用事件广播器,用于发布事件到相应的监听器。
  • LifecycleProcessor:生命周期处理器,用于处理生命周期事件。
  • Lifecycle:定义生命周期控制方法的接口,特别是 SmartLifecycle,可以在 Spring IoC 容器刷新完毕时进行触发。
  • ApplicationContextEvent:应用事件的基类。
  • ApplicationListener,应用事件监听器,用于监听应用事件。

 

 

程序员囧辉 CSDN认证博客专家 Spring MySQL 分布式
当你的才华还撑不起你的野心的时候,你就应该静下心来学习,愿你在我这里能有所收获。公众号:程序员囧辉,分享个人在Java学习路上的一些学习、思考、经验和总结。
©️2020 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值