Spring ioc容器创建过程(1)BeanFactory初始化 spring ioc容器创建过程(2)invokeBeanFactoryPostProcessors spring ioc容器创建过程(3)registerBeanPostProcessors
前三篇文章主要讲了beanFacctory的初始化,bean的后置处理器与beanFactory的后置处理器,这篇文章主要来分析下剩余部分。
1、initMessageSource()
这部分主要是用于spring国际化的功能,因为不常用就暂时不分析了。
2、initApplicationEventMulticaster()
看名字就知道了,这部分主要是来初始化spring的事件广播器的。这里主要用了设计模式的观察者模式,通过ApplicationEventMulticaster事件广播器实现了监听器的注册,通过ApplicationEvent抽象类和ApplicationListener接口,可以实现事件的处理。
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
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 {
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可以去注册监听器。注册好监听器后,广播会将对应的事件传递给监听器。
protected void registerListeners() {
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
5、finishBeanFactoryInitialization(beanFactory)
实例化所有单例的非懒加载的Bean,并完成依赖注入。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
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));
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
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);
}
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
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);
}
}
}
else {
getBean(beanName);
}
}
}
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) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
6、finishRefresh()
@SuppressWarnings("deprecation")
protected void finishRefresh() {
clearResourceCaches();
initLifecycleProcessor();
getLifecycleProcessor().onRefresh();
publishEvent(new ContextRefreshedEvent(this));
if (!IN_NATIVE_IMAGE) {
LiveBeansView.registerApplicationContext(this);
}
}
到这里基本上spring ioc容器的初始化就结束了。
|