29--ApplicationContext 创建过程以及refresh方法分析(三)

版权声明:如有转载,请标明出处,谢谢合作! https://blog.csdn.net/lyc_liyanchao/article/details/82849991

前两节已经介绍了BeanFactoryPostProcessor的调用过程和BeanPostProcessor的初始化过程,我们继续分析refresh()方法。

9.初始化事件广播器

spring中的事件机制,也是典型的观察者模式的实现,如果大家对观察者模式不熟悉的话,可以先去了解一下,将有助于接下来的理解。现在来看事件广播器的初始化过程。

/**
 * 初始化事件广播器
 * Initialize the ApplicationEventMulticaster.
 * Uses SimpleApplicationEventMulticaster if none defined in the context.
 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
 */
protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    // 默认使用内置的事件广播器,如果有的话.
    // 我们可以在配置文件中配置Spring事件广播器或者自定义事件广播器
    // 例如: <bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster"></bean>
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isTraceEnabled()) {
            logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    // 否则,新建一个事件广播器,SimpleApplicationEventMulticaster是spring的默认事件广播器
    else {
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isTraceEnabled()) {
            logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
                    "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
        }
    }
}

从代码中可以看到,Spring默认使用内置的事件广播器,例如我们可以在配置文件中定义一个事件广播器,注意beanName,

public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
<!--事件广播器-->
<bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster"></bean>

如果从BeanFactory中获取到了名为applicationEventMulticaster的事件广播器的话,那么就以此作为默认的事件广播器,如果未能获取的话,就要新建一个SimpleApplicationEventMulticaster类型的事件广播器,SimpleApplicationEventMulticaster也是Spring的默认事件广播器。
SimpleApplicationEventMulticaster–>AbstractApplicationEventMulticaster–>ApplicationEventMulticaster。

再加下来是onRefresh()方法,该方法是个空的模板方法,如果子类有需要的话,可以自己实现该方法,这也是spring的可扩展性的一个良好提现。

10.注册事件监听器

有了事件广播器之后,我们就要将事件监听器加入到事件广播器之后,以便事件广播器调用。

protected void registerListeners() {
    // Register statically specified listeners first.
    // 首先,注册指定的静态事件监听器,在spring boot中有应用
    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!
    // 其次,注册普通的事件监听器
    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...
    // 如果有早期事件的话,在这里进行事件广播
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

静态事件监听器和早期事件没搞明白,中间的普通事件监听器,我们可以通过实现ApplicationListener接口并重写onApplicationEvent来实现,通过xml配置文件来注册即可。

package com.lyc.cn.day06.event;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

/**
 * @author: LiYanChao
 * @create: 2018-09-26 10:53
 */
public class MyApplicationListener implements ApplicationListener {
	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		System.out.println("事件触发...");
	}
}
<!--自定义事件监听器-->
<bean id="myApplicationListener" class="com.lyc.cn.day06.event.MyApplicationListener"></bean>
11.初始化其他的单例Bean(非延迟加载的)
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    // 判断有无ConversionService(bean属性类型转换服务接口),并初始化
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    //
    // Register a default embedded value resolver if no bean post-processor
    // (such as a PropertyPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    // 如果beanFactory中不包含EmbeddedValueResolver,则向其中添加一个EmbeddedValueResolver
    // EmbeddedValueResolver-->解析bean中的占位符和表达式
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    // 初始化LoadTimeWeaverAware类型的bean
    // LoadTimeWeaverAware-->加载Spring Bean时织入第三方模块,如AspectJ
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // Stop using the temporary ClassLoader for type matching.
    // 释放临时类加载器
    beanFactory.setTempClassLoader(null);

    // Allow for caching all bean definition metadata, not expecting further changes.
    // 冻结缓存的BeanDefinition元数据
    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    // 初始化其他的非延迟加载的单例bean
    beanFactory.preInstantiateSingletons();
}

该过程比较简单,在初始化其他的非延迟加载的单例bean之前,预先加载了几个特殊的bean。

ConversionService–>判断有无自定义属性转换服务接口,并将其初始化,我们在分析bean的属性填充过程中,曾经用到过该服务接口。在TypeConverterDelegate类的convertIfNecessary方法中。

EmbeddedValueResolver–>内嵌的属性值解析器,主要用来解析bean中的占位符和表达式。

LoadTimeWeaverAware–>如果有LoadTimeWeaverAware类型的bean则初始化,用来加载Spring Bean时织入第三方模块,如AspectJ,我们在后面详细讲解。

最后初始化其他的普通的非延迟加载的bean,具体的代码如果大家看过之前的bean加载过程的话,应该很简单了,这里不再赘述。

12.完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知
protected void finishRefresh() {
    // Clear context-level resource caches (such as ASM metadata from scanning).
    // 清空资源缓存
    clearResourceCaches();

    // Initialize lifecycle processor for this context.
    // 初始化生命周期处理器
    initLifecycleProcessor();

    // Propagate refresh to lifecycle processor first.
    // 调用生命周期处理器的onRefresh方法
    getLifecycleProcessor().onRefresh();

    // Publish the final event.
    // 推送容器刷新事件
    publishEvent(new ContextRefreshedEvent(this));

    // Participate in LiveBeansView MBean, if active.
    // MBean...没弄明白
    LiveBeansView.registerApplicationContext(this);
}
  • 初始化生命周期处理器
protected void initLifecycleProcessor() {
    // 尝试从容器中获取lifecycleProcessor生命周期处理器
    // 我们可以实现Lifecycle接口,并在配置文件中进行如下配置
    // <bean id="myLifecycleBean" class="com.lyc.cn.day06.MyLifecycleBean"></bean>
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
        this.lifecycleProcessor = beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
        if (logger.isTraceEnabled()) {
            logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
        }
    }
    // 如果没有的话,则创建一个DefaultLifecycleProcessor作为默认的生命周期处理器
    else {
        DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
        defaultProcessor.setBeanFactory(beanFactory);
        this.lifecycleProcessor = defaultProcessor;
        beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
        if (logger.isTraceEnabled()) {
            logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
                    "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
        }
    }
}
  • 调用生命周期处理器的onRefresh方法
/**
 * 启动LifecycleBean的start方法.
 * autoStartupOnly:true-->则不会在这里启动
 * 				  :false-->启动
 */
private void startBeans(boolean autoStartupOnly) {
    Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
    Map<Integer, LifecycleGroup> phases = new HashMap<>();
    lifecycleBeans.forEach((beanName, bean) -> {
        if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
            int phase = getPhase(bean);
            LifecycleGroup group = phases.get(phase);
            if (group == null) {
                group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                phases.put(phase, group);
            }
            group.add(beanName, bean);
        }
    });
    if (!phases.isEmpty()) {
        List<Integer> keys = new ArrayList<>(phases.keySet());
        Collections.sort(keys);
        for (Integer key : keys) {
            phases.get(key).start();
        }
    }
}
  • 推送容器刷新事件
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
    Assert.notNull(event, "Event must not be null");

    // Decorate event as an ApplicationEvent if necessary
    ApplicationEvent applicationEvent;
    if (event instanceof ApplicationEvent) {
        applicationEvent = (ApplicationEvent) event;
    }
    else {
        applicationEvent = new PayloadApplicationEvent<>(this, event);
        if (eventType == null) {
            eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
        }
    }

    // Multicast right now if possible - or lazily once the multicaster is initialized
    // 如果earlyApplicationEvents不为空
    // 则说明早期事件不为空,则说明容器尚未初始化广播器,无法进行事件广播,我们将其存放到earlyApplicationEvents中
    // 待容器初始化事件广播器之后,再进行事件广播
    // 可以参考 registerListeners()方法
    // 至于哪些事件是早期事件,我也没弄明白...
    if (this.earlyApplicationEvents != null) {
        this.earlyApplicationEvents.add(applicationEvent);
    }
    else {
        getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
    }

    // Publish event via parent context as well...
    // 通知父容器发布事件
    if (this.parent != null) {
        if (this.parent instanceof AbstractApplicationContext) {
            ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
        }
        else {
            this.parent.publishEvent(event);
        }
    }
}
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    // 如过有任务处理池的话,则默认使用任务处理池来进行异步处理
    for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        Executor executor = getTaskExecutor();
        if (executor != null) {
            executor.execute(() -> invokeListener(listener, event));
        }
        // 否则同步处理
        else {
            invokeListener(listener, event);
        }
    }
}

代码会继续调用doInvokeListener方法

private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    try {
        // 调动onApplicationEvent方法
        listener.onApplicationEvent(event);
    }
    catch (ClassCastException ex) {
        String msg = ex.getMessage();
        if (msg == null || matchesClassCastMessage(msg, event.getClass().getName())) {
            // Possibly a lambda-defined listener which we could not resolve the generic event type for
            // -> let's suppress the exception and just log a debug message.
            Log logger = LogFactory.getLog(getClass());
            if (logger.isDebugEnabled()) {
                logger.debug("Non-matching event type for listener: " + listener, ex);
            }
        }
        else {
            throw ex;
        }
    }
}

代码执行到listener.onApplicationEvent(event);就会调用事件监听器的onApplicationEvent的方法,触发事件了。

ApplicationContext容器的refresh()方法讲到这里就结束了~

猜你喜欢

转载自blog.csdn.net/lyc_liyanchao/article/details/82849991