springboot2.1.7 start AbstractApplicationContext refresh (3)

table of Contents

registerListeners()

finishBeanFactoryInitialization(beanFactory)

finishRefresh()


registerListeners()

Check the listener beans and register them.

	protected void registerListeners() {
		// Register statically specified listeners first.
		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 collection obtained by getApplicationListeners(). Add these objects to the multicaster.

Then get the beanNames that implement ApplicationListener and add them to the multicaster. Then execute the application event early in the release.

finishBeanFactoryInitialization(beanFactory)

Instantiate all remaining (non-lazy initialized) singletons.

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
        // 为此上下文初始化转换服务
		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之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        //尽早初始化LoadTimeWeaverAware Bean,以便尽早注册其转换器
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
        //停止使用临时的ClassLoader进行类型匹配
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
        //冻结所有Bean定义,表示已注册的Bean定义将不再被修改或进一步处理。 这允许工厂积极地缓存bean定义元数据。因为接下来就要创建bean的实例了
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
        //确保所有非延迟初始单例都实例化,同时考虑到FactoryBeans 。 如果需要,通常在工厂设置结束时调用。
		beanFactory.preInstantiateSingletons();
	}

DefaultListableBeanFactory#preInstantiateSingletons 

	@Override
	public void preInstantiateSingletons() throws BeansException {

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
        //遍历一个副本以允许使用init methods ,这些方法依次注册新的bean定义。尽管这可能不是常规工厂引导程序的一部分,但可以正常运行
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
        //遍历beanNames,触发所有非懒加载单例bean的初始化
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            //不是抽象类 && 是单例 && 不是懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                //beanName对应的bean是否为FactoryBean
				if (isFactoryBean(beanName)) {
                    //获取FactoryBean实例
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final 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 {
                    //不是FactoryBean,获取bean实例
					getBean(beanName);
				}
			}
		}
		// Trigger post-initialization callback for all applicable beans...
        //触发所有适用bean的初始化后回调.这里只有SmartInitializingSingleton
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

SmartInitializingSingleton document translation: During the BeanFactory boot process, the callback interface is triggered at the end of the singleton pre-instancing phase. This interface can be implemented by a singleton bean in order to perform some initialization after the conventional singleton instantiation algorithm to avoid the side effects of unexpected early initialization (for example, from ListableBeanFactory.getBeansOfType call). In this sense, it is an alternative to InitializingBean, which is triggered immediately at the end of the bean's local construction phase.
This callback variant is somewhat similar to org.springframework.context.event.ContextRefreshedEvent but does not need to implement org.springframework.context.ApplicationListener and does not need to filter context references in the entire context hierarchy. This also means that more dependence on the beans package is minimal, and is fulfilled by the independent ListableBeanFactory implementation, not just in the org.springframework.context.ApplicationContext environment.
Note: If you want to start/manage asynchronous tasks, it is best to implement org.springframework.context.Lifecycle, which provides a richer model for runtime management and allows phased startup/shutdown

finishRefresh()

ServletWebServerApplicationContext#finishRefresh

	protected void finishRefresh() {
		super.finishRefresh();
        //启动web服务
		WebServer webServer = startWebServer();
        //推送web服务初始化完成事件到相应的监听器
		if (webServer != null) {
			publishEvent(new ServletWebServerInitializedEvent(webServer, this));
		}
	}

父类AbstractApplicationContext#finishRefresh

protected void finishRefresh() {
		// Clear context-level resource caches (such as ASM metadata from scanning).
		clearResourceCaches();

		// Initialize lifecycle processor for this context.
        //初始化LifecycleProcessor。 如果上下文中未定义,则使用DefaultLifecycleProcessor。
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
        //首先将刷新传播到生命周期处理器。例如swagger、quartz等实现了生命周期接口。
		getLifecycleProcessor().onRefresh();

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

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

 

Guess you like

Origin blog.csdn.net/sinat_33472737/article/details/113253180