SpringBoot 源码解析4:refresh 方法解析

news2024/11/19 6:29:19

SpringBoot 源码解析4:refresh 方法解析

    • 1. refresh 方法解析
    • 2. 准备刷新 AbstractApplicationContext#prepareRefresh
    • 3. 获取bean工厂 AbstractApplicationContext#obtainFreshBeanFactory
    • 4. 准备bean工厂 AbstractApplicationContext#prepareBeanFactory
    • 5. ServletWebServerApplicationContext#postProcessBeanFactory
    • 6. 调用BeanFactoryPostProcessor AbstractApplicationContext#invokeBeanFactoryPostProcessors
    • 7. BeanPostProcessor注册 AbstractApplicationContext#registerBeanPostProcessors
    • 8. 国际化支持 initMessageSource
    • 9. 初始化事件分发器 AbstractApplicationContext#initApplicationEventMulticaster
    • 10. 创建web容器 ServletWebServerApplicationContext#onRefresh
    • 11. 注册事件监听器 AbstractApplicationContext#registerListeners
    • 12. Bean的实例化 AbstractApplicationContext#finishBeanFactoryInitialization
      • 12.1 DefaultListableBeanFactory#finishBeanFactoryInitialization
      • 12.2 DefaultListableBeanFactory#preInstantiateSingletons
    • 13. 启动web容器 ServletWebServerApplicationContext#finishRefresh

1. refresh 方法解析

AbstractApplicationContext#refresh 方法为Spring最核心的方法,Bean的注册,实例化,初始化过程都是在此方法中完成的。

从SpringBoot启动流程可知,创建了ApplicationContext为AnnotationConfigServletWebServerApplicationContext,调用AbstractApplicationContext的refresh方法。
在这里插入图片描述

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		// 容器刷新前的准备工作
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		// 获取DefaultListableBeanFactory
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		// 对bean工厂准备工作,配置
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			// 配置BeanFactory,对web的支持
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			// 调用BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			// 注册BeanPostProcessor
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			// 对国际化支持
			initMessageSource();

			// Initialize event multicaster for this context.
			// 初始化事件发布器
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			// 创建web服务
			onRefresh();

			// Check for listener beans and register them.
			// 注册时间监听器
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			// 实例化bean核心方法
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			// 启动web服务,发布事件
			finishRefresh();
		}

		catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +
						"cancelling refresh attempt: " + ex);
			}

			// Destroy already created singletons to avoid dangling resources.
			destroyBeans();

			// Reset 'active' flag.
			cancelRefresh(ex);

			// Propagate exception to caller.
			throw ex;
		}

		finally {
			// Reset common introspection caches in Spring's core, since we
			// might not ever need metadata for singleton beans anymore...
			resetCommonCaches();
		}
	}
}

2. 准备刷新 AbstractApplicationContext#prepareRefresh

容器刷新前准备工作,对环境变量进行校验,初始化监听器等。

protected void prepareRefresh() {
	// Switch to active.
	this.startupDate = System.currentTimeMillis();
	this.closed.set(false);
	this.active.set(true);

	if (logger.isDebugEnabled()) {
		if (logger.isTraceEnabled()) {
			logger.trace("Refreshing " + this);
		}
		else {
			logger.debug("Refreshing " + getDisplayName());
		}
	}

	// Initialize any placeholder property sources in the context environment.
	initPropertySources();

	// Validate that all properties marked as required are resolvable:
	// see ConfigurablePropertyResolver#setRequiredProperties
	getEnvironment().validateRequiredProperties();

	// Store pre-refresh ApplicationListeners...
	if (this.earlyApplicationListeners == null) {
		this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
	}
	else {
		// Reset local application listeners to pre-refresh state.
		this.applicationListeners.clear();
		this.applicationListeners.addAll(this.earlyApplicationListeners);
	}

	// Allow for the collection of early ApplicationEvents,
	// to be published once the multicaster is available...
	this.earlyApplicationEvents = new LinkedHashSet<>();
}
  1. initPropertySources方法:对Environment中的servletContextInitParams和servletConfigInitParams的propertySource初始化。
  2. getEnvironment().validateRequiredProperties() 校验了是否存在requiredProperties中包含的必须存在的属性,否则会抛出MissingRequiredPropertiesException,requiredProperties默认为空。
  3. 初始化了事件监听器ApplicationListener和事件ApplicationEvent

3. 获取bean工厂 AbstractApplicationContext#obtainFreshBeanFactory

获取beanFactory,AnnotationConfigServletWebServerApplicationContext是GenericApplicationContext的子类,在实例化的时候,创建的是DefaultListableBeanFactory。

/**
* Create a new GenericApplicationContext.
 * @see #registerBeanDefinition
 * @see #refresh
 */
public GenericApplicationContext() {
	this.beanFactory = new DefaultListableBeanFactory();
}

4. 准备bean工厂 AbstractApplicationContext#prepareBeanFactory

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	// Tell the internal bean factory to use the context's class loader etc.
	beanFactory.setBeanClassLoader(getClassLoader());
	beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

	// Configure the bean factory with context callbacks.
	beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
	beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
	beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
	beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
	beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

	// BeanFactory interface not registered as resolvable type in a plain factory.
	// MessageSource registered (and found for autowiring) as a bean.
	beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
	beanFactory.registerResolvableDependency(ResourceLoader.class, this);
	beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
	beanFactory.registerResolvableDependency(ApplicationContext.class, this);

	// Register early post-processor for detecting inner beans as ApplicationListeners.
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

	// Detect a LoadTimeWeaver and prepare for weaving, if found.
	if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		// Set a temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}

	// Register default environment beans.
	if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
	}
}
  1. 为bean工厂做准备,对bean工厂进行了配置。
  2. 配置了ignoredDependencyInterfaces。在Spring注入的过程中,如果是ignoredDependencyInterfaces所包含的类型bean,会忽略注入。
  3. 配置了resolvableDependencies,key依赖类型,value依赖bean。在Spring注入的过程中,如果注入的类型为resolvableDependencies对应的key,则注入resolvableDependencies所对应的value。
  4. 添加了一些后置处理器BeanPostProcessor,注册了一些单例bean。
  5. 注册了与Environment相关的单例。

5. ServletWebServerApplicationContext#postProcessBeanFactory

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
	beanFactory.ignoreDependencyInterface(ServletContextAware.class);
	registerWebApplicationScopes();
}
  1. 注册后置处理器WebApplicationContextServletContextAwareProcessor,在bean初始化之前,对bean设置ServletContext和ServletConfig。忽略了ServletContextAware接口依赖。
  2. registerWebApplicationScopes注册了request、session、application作用域。
  3. 创建了ServletRequest、ServletResponse、HttpSession、WebRequest可依赖对象工厂。
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
		@Nullable ServletContext sc) {

	beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
	beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
	if (sc != null) {
		ServletContextScope appScope = new ServletContextScope(sc);
		beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
		// Register as ServletContext attribute, for ContextCleanupListener to detect it.
		sc.setAttribute(ServletContextScope.class.getName(), appScope);
	}

	beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
	beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
	beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
	beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
	if (jsfPresent) {
		FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
	}
}

6. 调用BeanFactoryPostProcessor AbstractApplicationContext#invokeBeanFactoryPostProcessors

主要逻辑委派到PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法,负责执行BeanDefinitionRegistry和BeanFactoryPostProcessor。

public static void invokeBeanFactoryPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

	// Invoke BeanDefinitionRegistryPostProcessors first, if any.
	//
	Set<String> processedBeans = new HashSet<>();

	// 当前beanFactory为DefaultListableBeanFactory,可以查看类结构,是属于BeanDefinitionRegistry类型的
	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
		//regularPostProcessors 存放的是BeanDefinitionRegistryPostProcessor(优先),registryProcessors 存放的是BeanFactoryPostProcessor,而BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口
		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
				BeanDefinitionRegistryPostProcessor registryProcessor =
						(BeanDefinitionRegistryPostProcessor) postProcessor;
				//先执行BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
				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.
		//首先,按照PriorityOrdered的顺序调用Spring容器中的BeanDefinitionRegistryPostProcessor
		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.
		//其次,按照Ordered的顺序调用Spring容器中的BeanDefinitionRegistryPostProcessor
		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.
		//最后,调用没有实现Ordered和PriorityOrdered的BeanDefinitionRegistryPostProcessor。但是SpringBoot内置了支持@Priority和@Order注解顺序比较器AnnotationAwareOrderComparator
		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.
		//最最后,在BeanDefinitionRegistryPostProcessor调用完毕之后,才会调用BeanFactoryPostProcessor。而且是先调用BeanDefinitionRegistryPostProcessor类型的BeanFactoryPostProcessor,再调用其他类型的BeanFactoryPostProcessor,这些BeanFactoryPostProcessor不是从beanFactory中获取的,而是之前流程手动添加到applicationContext中的。
		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!
	//在这里,才会获取beanFactory中的BeanFactoryPostProcessor,下面BeanFactoryPostProcessor调用的顺序和BeanDefinitionRegistryPostProcessor调用的顺序逻辑一样的。先按照PriorityOrdered,其次Ordered,最后调用无序的
	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<>(orderedPostProcessorNames.size());
	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<>(nonOrderedPostProcessorNames.size());
	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();
}
  1. 此方法主要负责调用BeanDefinitionRegistry和BeanFactoryPostProcessor。调用顺序如下:
    1.1. 先调用BeanDefinitionRegistry再调用BeanFactoryPostProcessor。
    1.2. 先调用手动注册的BeanDefinitionRegistry,再调用beanFactory中的BeanDefinitionRegistry。
    1.3. PriorityOrdered接口顺序 > Ordered接口顺序 > @Priority和@Order顺序 > 无序。
    1.4. BeanFactoryPostProcessor调用顺序和BeanDefinitionRegistry调用一样。
  2. 在SpringBoot启动流程中,创建ApplicationContext中的scanner的时候,手动注册了ConfigurationClassPostProcessor,而ConfigurationClassPostProcessor是Spring注解式支持的核心。在调用ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法的过程中,Spring将需要注册的Bean的信息(比如:@Component注解标注的类)注册到DefaultListableBeanFactory#beanDefinitionMap,以便实例化。
  3. TODO 请后续请参考 ConfigurationClassPostProcessor。
  4. 为什么每次调用BeanDefinitionRegistryPostProcessor,都要从beanFactory中获取,而调用BeanFactoryPostProcessor只获取了一次?
    4.1. 因为BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry方法的用途是注册BeanDefinition的,在调用完BeanDefinitionRegistryPostProcessor之后,又会产生新的BeanDefinition,而这些的"新的BeanDefinition"有可能是BeanDefinitionRegistryPostProcessor。
    4.2. BeanFactoryPostProcessor只是修改beanDefinition的属性而已,不会产生新的BeanDefinition。

7. BeanPostProcessor注册 AbstractApplicationContext#registerBeanPostProcessors

从方法名称上就能知道,这个方法是注册BeanPostProcessor。实际上就是把存放在DefaultListableBeanFactory#beanDefinitionMap中的bean的定义信息实例化,保存到AbstractBeanFactory#beanPostProcessors。

public static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

	// Register BeanPostProcessorChecker that logs an info message when
	// a bean is created during BeanPostProcessor instantiation, i.e. when
	// a bean is not eligible for getting processed by all BeanPostProcessors.
	int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

	// Separate between BeanPostProcessors that implement PriorityOrdered,
	// Ordered, and the rest.
	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
	List<String> orderedPostProcessorNames = new ArrayList<>();
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	for (String ppName : postProcessorNames) {
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			priorityOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		}
		else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// First, register the BeanPostProcessors that implement PriorityOrdered.
	// 顺序1:按照PriorityOrdered排序,然后注册
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// Next, register the BeanPostProcessors that implement Ordered.
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
	for (String ppName : orderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		orderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	// 顺序2:按照Ordered排序,然后注册
	sortPostProcessors(orderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

	// Now, register all regular BeanPostProcessors.
	List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
	for (String ppName : nonOrderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		nonOrderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	//顺序3:注册无序的beanPostProcessor
	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

	// Finally, re-register all internal BeanPostProcessors.
	//顺序4:对MergedBeanDefinitionPostProcessor排序,然后重新注册。先remove,再add
	sortPostProcessors(internalPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, internalPostProcessors);

	// Re-register post-processor for detecting inner beans as ApplicationListeners,
	// moving it to the end of the processor chain (for picking up proxies etc).
	//顺序5:注册ApplicationListenerDetector
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
  1. BeanPostProcessor的注册顺序就是后期方法回调的顺序,它的顺序和BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor调用的顺序几乎是一样的。
  2. by PriorityOrdered > by Ordered > 无序 > MergedBeanDefinitionPostProcessor > ApplicationListenerDetector。
  3. 注册逻辑:AbstractBeanFactory#addBeanPostProcessor,先remove在add。
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
	Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
	// Remove from old position, if any
	this.beanPostProcessors.remove(beanPostProcessor);
	// Track whether it is instantiation/destruction aware
	if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
		this.hasInstantiationAwareBeanPostProcessors = true;
	}
	if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
		this.hasDestructionAwareBeanPostProcessors = true;
	}
	// Add to end of list
	this.beanPostProcessors.add(beanPostProcessor);
}

8. 国际化支持 initMessageSource

这里是对国际化的支持,后续单独再起文章

9. 初始化事件分发器 AbstractApplicationContext#initApplicationEventMulticaster

初始化事件分发器SimpleApplicationEventMulticaster,负责事件的分发。

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(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
		if (logger.isTraceEnabled()) {
			logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
					"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
		}
	}
}
  1. 判断是否存在名称为applicationEventMulticaster的bean或者beanDenifition或者factoryBean。
  2. 如果存在,则返回,不存在则注册一个SimpleApplicationEventMulticaster。
  3. SimpleApplicationEventMulticaster负责事件的分发,参考SpringBoot 源码解析2:启动流程
  4. 为什么SpringBoot启动的时候已经创建了SimpleApplicationEventMulticaster,但是此时在AbstractApplicationContext#refresh还需要注册SimpleApplicationEventMulticaster?
    4.1. 之前SpringBoot启动的时候,是在SpringApplication内完成的,它的ApplicationListener监听器是手动注册的,为了监听SpringBoot启动的整个过程。
    4.2. 此时注册SimpleApplicationEventMulticaster是注册到BeanFactory中,给用户使用的,用户可以自定义事件和监听器处理业务。

10. 创建web容器 ServletWebServerApplicationContext#onRefresh

此方法创建了web容器,为了后续启动Servlet。通过加载的@ConditionalOnClass判断类是否加载,众所周知,SpringBoot内置了Tomcat,注册了TomcatServletWebServerFactory。
下面是Servlet容器自动配置:
在这里插入图片描述

private void createWebServer() {
	WebServer webServer = this.webServer;
	ServletContext servletContext = getServletContext();
	if (webServer == null && servletContext == null) {
	    //获取Servlet容器工厂
		ServletWebServerFactory factory = getWebServerFactory();
		//启动tomcat,并在tomcat声明周期Start的时候回调ServletContextInitializer
		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();
}

protected ServletWebServerFactory getWebServerFactory() {
	// Use bean names so that we don't consider the hierarchy
	String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
	if (beanNames.length == 0) {
		throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing "
				+ "ServletWebServerFactory bean.");
	}
	if (beanNames.length > 1) {
		throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple "
				+ "ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
	}
	return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
}
  1. 从BeanFactory中获取ServletWebServerFactory,获取的是TomcatServletWebServerFactory。
  2. 获取Servlet容器工厂,在tomcat声明周期Start的时候回调ServletContextInitializer,返回webServer。

11. 注册事件监听器 AbstractApplicationContext#registerListeners

注册事件监听器

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);
		}
	}
}
  1. 从SpringBoot启动流程可知,在SpringApplication#prepareContext方法中,已经将SpringApplication中的事件监听器copy到了ApplicationContext中。
  2. 而这里先将ApplicationListener实例注册,在将Bean工厂中的属于ApplicationListener的beanName注册。
  3. 监听器的回调原理请参考:SpringBoot 源码解析3:事件监听器

12. Bean的实例化 AbstractApplicationContext#finishBeanFactoryInitialization

完成BeanFactory对bean的实例化,在此之前,所有的beanDefinition都已注册到DefaultListableBeanFactory#beanDefinitionMap。

12.1 DefaultListableBeanFactory#finishBeanFactoryInitialization

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.
	beanFactory.setTempClassLoader(null);

	// Allow for caching all bean definition metadata, not expecting further changes.
	// 冻结beanDinifition,不期望后期beanDinition再被修改
	beanFactory.freezeConfiguration();

	// Instantiate all remaining (non-lazy-init) singletons.
	// 实例化的真正逻辑
	beanFactory.preInstantiateSingletons();
}

此方法很简单,看注释。

12.2 DefaultListableBeanFactory#preInstantiateSingletons

@Override
public void preInstantiateSingletons() throws BeansException {
	if (logger.isTraceEnabled()) {
		logger.trace("Pre-instantiating singletons in " + this);
	}

	// 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.
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

	// Trigger initialization of all non-lazy singleton beans...
	// 获取到所有BeanDifinition注册的beanName,遍历创建
	for (String beanName : beanNames) {
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
		    // 判断当前的bean是否为FactoryBean
			if (isFactoryBean(beanName)) {
			    // 如果是FactoryBean,那么就获取到当前的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());
					}
					//如果factoryBean是SmartFactoryBean,并且是迫切加载,那么就实例化当前bean
					if (isEagerInit) {
						getBean(beanName);
					}
				}
			}
			else {
			    //如果不是FactoryBean,那么就创建
				getBean(beanName);
			}
		}
	}

	// Trigger post-initialization callback for all applicable beans...
	// 判断单例池中的bean如果是SmartInitializingSingleton,那么就回调afterSingletonsInstantiated方法
	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();
			}
		}
	}
}
  1. 判断当前的bean是否属于FactoryBean类型,如果不是FactoryBean类型,那么就直接去创建当前bean。如果不是FactoryBean,并且为SmartFactoryBean,判断是否要迫切加载。
  2. 判断单例池中的bean如果是SmartInitializingSingleton,那么就回调afterSingletonsInstantiated方法。

13. 启动web容器 ServletWebServerApplicationContext#finishRefresh

@Override
protected void finishRefresh() {
	super.finishRefresh();
	WebServer webServer = startWebServer();
	if (webServer != null) {
		publishEvent(new ServletWebServerInitializedEvent(webServer, this));
	}
}

启动web容器,发布ServletWebServerInitializedEvent事件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1389821.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows解决.conda文件夹占用C盘空间过大的问题

背景&#xff1a;C盘空间被.conda文件占用16G&#xff0c;主要原因是里面存放了python环境&#xff0c;提前进行环境迁移&#xff0c;防止后面环境增长C盘空间不足 解决办法&#xff1a; 1. .conda文件备份 2. 将.conda文件夹中的envs内容复制到Anaconda的安装目录下D:\Softwa…

HNU-编译原理-实验2-Bison

编译原理实验2Bison 计科210X 甘晴void 202108010XXX 实验要求 详细的实验项目文档为 https://gitee.com/coderwym/cminus_compiler-2023-fall/tree/master/Documentations/lab2 实验步骤 本次实验需要在 Lab1 已完成的 flex 词法分析器的基础上&#xff0c;进一步使用 b…

车机联网

通过笔记本电脑&#xff0c;D-link给车机提供网络 因为笔记本用的无线网络上网&#xff0c;将无线网络连接设置为共享 设置后的效果 本地连接属性设置 Dlink连接电脑和车机&#xff1b;获取车机的动态ip&#xff08;动态ip每次开关机都会变化&#xff0c;注意更新&#xff09…

【python 的各种模块】(9) 在python使用PIL( 即pillow模块 ) 修改图片

目录 1 导入PIL模块&#xff08;pillow&#xff09; 1.1 PIL的全称&#xff1a;Python Imaging Library 1.2 导入PIL模块 1.2.1 可用的导入形式 1.2.2 常用的导入形式 1.2.3 PIL下面的常用子模块 2 PIL.Image的方法 (读入&#xff0c;生成和显示图片) 2.1 用 PIL.Image…

《教育》期刊是什么级别的期刊?是正规期刊吗?能评职称吗?

《教育》以教育行业的各类新闻为重点&#xff0c;积极推广各地教育部门改革经验及优秀成果&#xff0c;努力挖掘教育一线先进单位和个人&#xff0c;充分发挥新闻舆论的监督作用。 收录情况&#xff1a;知网收录 投稿方式&#xff1a;教育类&#xff5c;《教育》省级 出版周期&…

GPT2 GPT3

what is prompt 综述1.Pre-train, Prompt, and Predict: A Systematic Survey of Prompting Methods in Natural Language Processing(五星好评) 综述2. Paradigm Shift in Natural Language Processing(四星推荐) 综述3. Pre-Trained Models: Past, Present and Future Pro…

Vue学习笔记5-- nextTick | Vue封装的过渡与动画

一、nextTick(tick-工作&#xff0c;起作用&#xff1b;下次起作用&#xff09; 语法&#xff1a; this.$nextTick(回调函数&#xff09;作用&#xff1a;在下一次DOM更新结束后执行其指定的回调。什么时候用&#xff1a;当改变数据后&#xff0c;要基于更新后的新DOM进行某些…

虾皮电商 电商平台:虾皮(Shopee)东南亚领先的电子商务平台

在当今数字化时代&#xff0c;电子商务平台的兴起改变了人们的购物方式。虾皮&#xff08;Shopee&#xff09;作为东南亚地区领先的电子商务平台&#xff0c;为消费者提供了便捷、多样化的购物体验。由新加坡的Sea Group&#xff08;前称Garena&#xff09;于2015年创立&#x…

程序员书单|本月有哪些新书值得关注?

2024年的第一个月&#xff0c;看了一下计算机书籍的榜单&#xff0c;本周有这样几本新书上榜。 1、GPT图解 大模型是怎样构建的 带你从0到1构建大模型&#xff0c;突破语言奥秘&#xff0c;开启智能未来&#xff01;深入探索自然语言处理技术的核心原理&#xff0c;结合实战&a…

【Linux】第二十九站:再谈进程地址空间

文章目录 一、一些疑问二、程序没有加载前的地址&#xff08;程序)三、程序加载后的地址四、动态库的地址 一、一些疑问 什么是虚拟地址&#xff1f;什么是物理地址&#xff1f;CPU读到的指令里面用的地址&#xff0c;是什么地址&#xff1f;&#xff1f; 我们之前在使用动态…

将web如vue等项目部署到宝塔docker镜像中,以便能在任意浏览器访问

文章目录 一、准备工作二、具体步骤1、从已经推送的镜像中拉取镜像2、切换到宝塔-容器&#xff0c;添加容器3、启动容器4、将刚刚的端口号添加到防火墙白名单5、访问部署好的项目 参考资料 一、准备工作 仅需确认宝塔面板已经有docker镜像容器 目前新版宝塔面板都已经内置了d…

数据结构之list类

前言 list是列表类。从list 类开始&#xff0c;我们就要接触独属于 Python 的数据类型了。Python 简单、易用&#xff0c;很大一部分原因就是它对基础数据类型的设计各具特色又相辅相成。 话不多说&#xff0c;让我们开始学习第一个 Python 数据类型一list。 1. list的赋值 输…

做完十年数据分析后的思考与总结

种一棵树最好的时间是十年前&#xff0c;其次是现在。十年了&#xff0c;本次分享大多来自工作中的日常所思所想&#xff0c;欢迎自取。 01 数据分析的本质 数据是基础&#xff0c;分析才是重点。 行业内有专门的统计岗&#xff0c;就是只负责做好数据统计就可以了&#xff0…

使用pycocotools打印更多数据(注意,修改后最好再还原!最好是一次性使用)

文章目录 1 写在前面2 代码效果3 代码修改 1 写在前面 夹带私货&#xff0c;可能有用呢&#xff1a;YOLOv7-tiny&#xff0c;通过pycocotools包得到预测大中小尺寸目标的指标值 仅供参考&#xff01;写这个代码的目的是能够打印出iou0.50的AP、AR的小中大3个尺寸的值&#xff…

记录汇川:H5U与Factory IO测试14

现实53工位的物料运输。 设置了自动连续存启动&#xff1a;就是一个一个运&#xff0c;按照顺序将空的货架填满。 设置了自动连续存停止&#xff1a;就是完成当前循环后退出。 设置了自动连续取启动&#xff1a;就是一个一个运&#xff0c;按照顺序将有货的货架清空。 设置…

Linux系统:yum仓库

目录 一、yum 1、yum概述 2、yum仓库 3、yum实现过程原理 二、yum配置文件详解 1、主配置文件 2、yum仓库设置文件 3、yum日志文件 三、yum命令详解 1、查询 1.1 yum list [软件名] 1.2 yum info [软件名] 1.3 yum search <关键词> 1.4 yum provides <关…

从0到1:实验室设备借用小程序开发笔记

概论 实验室设备借用小程序&#xff0c;适合各大高校&#xff0c;科技园区&#xff0c;大型企业集团的实验室设备借用流程, 通过数字化的手段进一步提升相关单位设备保障水平&#xff0c;规范实验室和设备管理&#xff0c;用户通过手机小程序扫描设备的二维码&#xff0c;可以…

1 vue防抖和限流

简介 什么是防抖 防抖&#xff08;Debouncing&#xff09;是一种前端开发中常用的技术&#xff0c;用于限制函数的执行频率。在防抖的机制下&#xff0c;一个函数在一定时间内只会执行一次&#xff0c;即使它被频繁地调用。 具体来说&#xff0c;防抖的实现方式是设置一个定…

【数据库8.0备份还原】之Percona XtraBackup

目录 Percona XtraBackup备份数据库1、Percona XtraBackup的介绍2、Percona XtraBackup安装3、Percona XtraBackup8.0的使用1.全库备份和还原2.增量备份和还原3.差异备份和还原4.差异备份和增量备份的区别5.压缩备份和还原 Percona XtraBackup备份数据库 yum源安装&#xff1a…

【技术分享】远程透传网关-单网口快速实现西门子S7-300/400 PLC程序远程上下载

准备工作 一台可联网操作的电脑一台单网口的远程透传网关及博达远程透传配置工具网线一条&#xff0c;用于实现网络连接和连接PLC一台西门子S7- 300/400 PLC及其编程软件一张4G卡或WIFI天线实现通讯(使用4G联网则插入4G SIM卡&#xff0c;WIFI联网则将WIFI天线插入USB口&#…