上一篇中,我们了解了spring中是如何基于事件驱动开发的,其实就是将监听器注册到事件广播器中,然后当spring发布事件时,事件广播器会遍历所有注册的监听器,并通过监听该事件的监听器来处理事件。这一篇中,我们继续将下面的方法:
我们进到onRefresh方法中看下:
可以看到方法onRefresh也是一个空方法,这个也是通过关键词protected修饰了,也就是说该方法onRefresh也是Spring留给子类的一个扩展方法。我们继续往下看:
我们进到这个registerListener方法中看下:
这个方法就是将参数中的监听器以及spring容器中获取到的监听器,分别注册到广播器中。所以为什么我们上一篇中,可以通过广播器获取到这些监听器了。
我们在看下refresh中其他的方法:
我们先看下这个finishRefresh方法,我们跟进去看下:
这个里面主要是初始化和生命周期相关的一些组件,我们可以先到方法initLifecycleProcessor中看下:
可以看到方法在initLifecycleProcessor中,首先就是到spring容器中看下是否存在名称lifecycleProcessor的bean。如果存在的话,就直接从spring容器中获取出来,并且赋值给成员变量lifecycleProcessor,如果不存在的话默认会创建一个DefaultLifecycleProcessor类型的对象,并且赋值给成员变量lifecycleProcessor,最后注入到spring容器中,那这个DefaultLifecycleProcessor又是什么呢?其实DefaultLifecycleProcessor在spring中,出来spring声明周期相关的一个组件,spring提供声明周期的接口Lifecycle,我们可以通过这个DefaultLifecycleProcessor类图看下:
可以看到,DefaultLifecycleProcessor最终实现的接口Lifecycle的,而LifecycleProcessor接口也只不过是Lifecycle接口的一个扩展接口而已,我们看下这个两个接口的方法:
在spring中如果bean实现了接口Lifecycle,spring会保证在容器启动时,就会调用这些bean中的start方法开启它们的声明周期,当然,在spring关闭的时候也会调用stop方法来结束它们的声明周期。而LifecycleProcessor在Lifecycle的基础上又添加了两个方法onRefresh和OnClose,主要就是对bean的状态进行更新,我们可以看下这个方法:
我们进入到方法中:
可以看到在onRefresh方法中,会从spring容器中获取所有实现了Lifecycle接口的bean,然后调用start方法来开启它们的声明周期。
最后,我们看下finishRefresh最后的一些逻辑:
可以看到,其实就是发布了一个刷新上下文的事件ContextRefreshedEvent,我们可以获取到这个事件进行相应的操作,比如系统启动时执行一些定时任务。
我们最后看下refresh的一个非常关键的方法:
这个finishBeanFactoryInitialization 方法非常的重要,接下来我们都是围绕这个方法讲的。我们先简单到这个方法里面看下:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 1、从spring容器 beanFactory中获取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 BeanFactoryPostProcessor
// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 获取spring容器中beanFactory中,实现接口LoadTimeWeaverAware的bean名称
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
// 提前调用getBean方法,尽早的初始化这些名称对应的bean
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 初始化非延迟加载的单例bean
beanFactory.preInstantiateSingletons();
}
可以看到,在finishBeanFactoryInitialization方法中,其实初始化了一下bean,我们重点的看下beanFactory调用的方法preInstantiateSingletons:
我们进到方法看下:
可以看到,在方法preInstantiateSingletons中,首先会遍历所有注册到spring容器中的BeanDefinition,如果BeanDefinition的属性scope的值为singleton也就是单例的,同时属性lazyInit的值wei false,说明该BeanDefinition对应的bean是不允许懒加载的单例bean。既然bean不允许懒加载,那当然就要立马去加载它了,所以,我们可以看到接下来就会调用getBean方法去实例化bean了。
我们先总结一下今天的内容: