springboot2.1.7启动 AbstractApplicationContext refresh(二)

目录

 

invokeBeanFactoryPostProcessors(beanFactory)

registerBeanPostProcessors(beanFactory)

initMessageSource()

initApplicationEventMulticaster()

onRefresh()


invokeBeanFactoryPostProcessors(beanFactory)

调用在上下文中注册为bean的工厂处理器。(实例化并调用所有注册的BeanFactoryPostProcessor Bean,并遵循显式顺序(如果给定的话)。必须在单例实例化之前调用)

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}
	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
        //如果有的话,首先调用BeanDefinitionRegistryPostProcessors。
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 用于存放普通的BeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            // 用于存放BeanDefinitionRegistryPostProcessor
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
	}
  •  processedBeans 执行过的processor对应的bean名称。(上述方法会多次获取相同类型的processedBean,执行过的存到该集合中,防止多次执行)
  •  如果有的话,首先调用BeanDefinitionRegistryPostProcessors。可以看出将目前的BeanFactoryPostProcessor分类存到不同的集合中。BeanDefinitionRegistryPostProcessor实例的执行对应的postProcessBeanDefinitionRegistry方法,存到registryProcessors(和bean定义注册相关的)。普通的直接存到regularPostProcessors中。

CachingMetadataReaderFactoryPostProcessor(ApplicationContextInitializer实现类SharedMetadataReaderFactoryContextInitializer调用initialize方法时添加的)属于BeanDefinitionRegistryPostProcessor。首先注册了一个class为SharedMetadataReaderFactoryBean的bean定义。然后配置了ConfigurationClassPostProcessor对应的bean定义,添加了一个metadataReaderFactory名称的属性,值为持有上述SharedMetadataReaderFactoryBean对应bean定义名称的引用RuntimeBeanReference(当引用工厂中的另一个bean时,用于属性值对象的不可变占位符类,将在运行时解析)

		public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
			register(registry);
			configureConfigurationClassPostProcessor(registry);
		}

		private void register(BeanDefinitionRegistry registry) {
			BeanDefinition definition = BeanDefinitionBuilder
					.genericBeanDefinition(SharedMetadataReaderFactoryBean.class, SharedMetadataReaderFactoryBean::new)
					.getBeanDefinition();
			registry.registerBeanDefinition(BEAN_NAME, definition);
		}

		private void configureConfigurationClassPostProcessor(BeanDefinitionRegistry registry) {
			try {
				BeanDefinition definition = registry
						.getBeanDefinition(AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME);
				definition.getPropertyValues().add("metadataReaderFactory", new RuntimeBeanReference(BEAN_NAME));
			}
			catch (NoSuchBeanDefinitionException ex) {
			}
		}
  • 接着会处理实现了PriorityOrdered接口的所有BeanDefinitionRegistryPostProcessor。首先获取到BeanDefinitionRegistryPostProcessor类型的bean名称。在这里会获取到ConfigurationClassPostProcessor对应的bean名称"org.springframework.context.annotation.internalConfigurationAnnotationProcessor",然后获取到ConfigurationClassPostProcessor示例,ConfigurationClassPostProcessor实现了PriorityOrdered接口,所以会添加到currentRegistryProcessors集合中(后续会执行的BeanDefinitionRegistryPostProcessor),排序号存放到上述registryProcessors中。接着会依次执行这些BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。执行完清空currentRegistryProcessors。
  • 同上再次获取Ordered接口的所有BeanDefinitionRegistryPostProcessor,然后重复上述步骤。
  • 调用所有其他BeanDefinitionRegistryPostProcessor,直到没有其他的出现。所以这里会通过reiterate变量判断是否循环获取BeanDefinitionRegistryPostProcessor执行。直到没有可以执行的会设置为false.
    同上再次所有BeanDefinitionRegistryPostProcessor,然后重复上述步骤。比如若项目中引入了mybatis,这里会获取到MapperScannerConfigurer这个BeanDefinitionRegistryPostProcessor,MapperScannerConfigurer没有实现Ordered接口,所以不会再上一步执行,而是会在这一步执行。
  • 调用到目前为止已处理的所有处理器的postProcessBeanFactory回调(BeanFactoryPostProcessor的回调扩展接口)
  • 最后,获取所有BeanFactoryPostProcessor,依次分为实现了PriorityOrdered接口的、实现了Ordered接口的和其它。然后依次按着三种类型执行postProcessBeanFactory回调。
  •  结尾beanFactory.clearMetadataCache():父类AbstractBeanFactory方法clearMetadataCache文档翻译:
    清除合并的bean定义高速缓存,删除尚未被认为适合完全元数据高速缓存的bean条目。通常在更改原始bean定义之后触发,例如在应用BeanFactoryPostProcessor之后触发。 请注意,此时将保留已经创建的bean的元数据。

总结: 先执行已初始化的BeanDefinitionRegistryPostProcessor,然后按照依次实现了PriorityOrdered接口的、实现了Ordered接口的和其它的BeanDefinitionRegistryPostProcessor对应的bean定义且初始化并执行。接着调用这些BeanDefinitionRegistryPostProcessor父类BeanFactoryPostProcessor的扩展接口。 接着按照依次实现了PriorityOrdered接口的、实现了Ordered接口的和其它的BeanFactoryPostProcessor对应的bean定义且初始化并执行。

registerBeanPostProcessors(beanFactory)

注册拦截Bean创建的Bean处理器BeanPostProcessor(文档翻译:实例化并注册所有BeanPostProcessor Bean,并遵循显式顺序(如果有的话)。必须在应用程序bean的任何实例化之前调用。)

可总结如下:按照依次实现了PriorityOrdered接口的、实现了Ordered接口的和其它的BeanPostProcessor 对应的bean定义且初始化并添加到beanFactory中。然后将其中的属于MergedBeanDefinitionPostProcessor的实例重新注册

initMessageSource()

为此上下文初始化message source。注册了一个bean名称为messageSource的单例bean对象,值为DelegatingMessageSource

initApplicationEventMulticaster()

为上下文初始化事件多播器。注册了一个bean名称为applicationEventMulticaster的单例bean对象,值为SimpleApplicationEventMulticaster

onRefresh()

在特定上下文子类中初始化其他特殊bean。(下方方法在ServletWebServerApplicationContext中)

	protected void onRefresh() {
		super.onRefresh();
		try {
			createWebServer();
		}
		catch (Throwable ex) {
			throw new ApplicationContextException("Unable to start web server", ex);
		}
	}

 由于使用的是默认的tomcat容器,所以下方ServletWebServerFactory 实例为TomcatServletWebServerFactory,获取到的webServer为TomcatWebServer

	private void createWebServer() {
		WebServer webServer = this.webServer;
		ServletContext servletContext = getServletContext();
		if (webServer == null && servletContext == null) {
			ServletWebServerFactory factory = getWebServerFactory();
			this.webServer = factory.getWebServer(getSelfInitializer());
		}
		else if (servletContext != null) {
			try {
				getSelfInitializer().onStartup(servletContext);
			}
			catch (ServletException ex) {
				throw new ApplicationContextException("Cannot initialize servlet context", ex);
			}
		}
		initPropertySources();
	}

猜你喜欢

转载自blog.csdn.net/sinat_33472737/article/details/113147082