文章目录
- 1、initMessageSource()
- 2、initApplicationEventMulticaster()
- 3、onRefresh()
- 4、registerListeners()
- 5、finishBeanFactoryInitialization(beanFactory)
- 5.1、 DefaultListableBeanFactory#preInstantiateSingletons()
- 6、finishRefresh()
Spring ioc容器创建过程(1)BeanFactory初始化spring ioc容器创建过程(2)invokeBeanFactoryPostProcessorsspring ioc容器创建过程(3)registerBeanPostProcessors
前三篇文章主要讲了beanFacctory的初始化,bean的后置处理器与beanFactory的后置处理器,这篇文章主要来分析下剩余部分。
1、initMessageSource()
这部分主要是用于spring国际化的功能,因为不常用就暂时不分析了。
2、initApplicationEventMulticaster()
看名字就知道了,这部分主要是来初始化spring的事件广播器的。这里主要用了设计模式的观察者模式,通过ApplicationEventMulticaster事件广播器实现了监听器的注册,通过ApplicationEvent抽象类和ApplicationListener接口,可以实现事件的处理。
/**
* 如果用户自定义了事件广播器,那么使用用户自定义的事件广播器。
* 如果用户没有自定义事件广播器,那么使用默认的ApplicationEventMulticaster即SimpleApplicationEventMulticaster。
*
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
//获取初始化好后的beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//bean工厂是否有applicationEventMulticaster这个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 + "]");
}
} else {
//否则就创建SimpleApplicationEventMulticaster类作为aplicationEventMulticaster的Bean
//SimpleApplicationEventMulticaster是aplicationEventMulticaster接口的一个实现
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
if (this.logger.isTraceEnabled()) {
this.logger.trace("No 'applicationEventMulticaster' bean, using [" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
可以推断, 当产生Spring 事件的时候会默认使用Simpl巳ApplicationEventMulticaster 的multicastEvent 来广播事件,遍历所有监昕器,并使用监昕器中的onApplicationEvent 方法来进行监昕器的处理。而对于每个监听器来说其实都可以获取到产生的事件,但是是否进行处理则由事件监听器来决定。
3、onRefresh()
模板方法,留给子类实现,像springboot就实现了其方法作为tomcat容器的启动。
4、registerListeners()
2的过程已经初始化了spring的事件广播器,通过registerListeners可以去注册监听器。注册好监听器后,广播会将对应的事件传递给监听器。
/**
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
*/
protected void registerListeners() {
// 手动注册的监听器绑定到广播器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
//取到容器里面的所有的监听器的名称,绑定到广播器
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 如果存在早期应用事件就直接发布(同时就把earlyApplicationEvents该字段置为null)
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
5、finishBeanFactoryInitialization(beanFactory)
实例化所有单例的非懒加载的Bean,并完成依赖注入。
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化上下文的转换服务,ConversionService是一个类型转换接口,作用即处理自定义的转换类型
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));
}
//主要用于注释属性值的解析
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 初始化 LoadTimeWeaverAwareBean 用于织入第三方模块,在 class 文件载入 JVM 的时候动态织入
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
//将临时类加载器设置为null
beanFactory.setTempClassLoader(null);
//冻结(缓存)所有的bean定义(ean definition),说明注册的bean 定义将不被修改或任何进一步的处理
beanFactory.freezeConfiguration();
//初始化剩下的单实例(非懒加载的)
beanFactory.preInstantiateSingletons();
}
5.1、 DefaultListableBeanFactory#preInstantiateSingletons()
ApplicationContext 实现的默认行为就是在启动时将所有单例bean 提前进行实例化。提前实例化意味着作为初始化过程的一部分, ApplicationContext 实例会创建并配置所有的单例bean. 通常情况下这是一件好事,因为这样在配置中的任何错误就会即刻被发现。而这个实例化的过程就是在finishBeanFactorylnitialization 中完成的。这部分先简单过一下,下次开个专栏分析下。
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 获取所有的beanName
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 初始化所有的非懒加载的单例bean
for (String beanName : beanNames) {
//对bean定义进行合并,如bean中引入parent属性
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 不是抽象类,是单例的,不是懒加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 如果是工厂Bean,那就会此工厂Bean放进去
if (isFactoryBean(beanName)) {
//如果是工厂bean,调用的时候再bean的名称前面添加前缀符号&
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
//拿到对应的bean后再次判断bean是否是factoryBean
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
// 非FactoryBean初始化
else {
getBean(beanName);
}
}
}
//再次遍历beanNames,对实现了SmartInitializingSingleton接口的类实现处理,会调用到该bean的afterSingletonsInstantiated()方法。
//在单例bean加载完成后,做一些事情
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
//native方法 不用做权限检查
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
6、finishRefresh()
/**
* Finish the refresh of this context, invoking the LifecycleProcessor's
* onRefresh() method and publishing the
* {@link org.springframework.context.event.ContextRefreshedEvent}.
*/
@SuppressWarnings("deprecation")
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
//初始化生命周期管理器LifecycleProcessor
initLifecycleProcessor();
//启动所有实现了Lifecycle接口的bean
getLifecycleProcessor().onRefresh();
//发布刷新完成事件
publishEvent(new ContextRefreshedEvent(this));
if (!IN_NATIVE_IMAGE) {
LiveBeansView.registerApplicationContext(this);
}
}
到这里基本上spring ioc容器的初始化就结束了。