SpringBoot(十四)启动流程分析之refreshContext()

SpringBoot版本:2.1.1     ==》启动流程分析汇总

接上篇Spring Boot 2.1.1(十三)启动流程分析之准备应用上下文

目录

流程分析 

1、准备刷新

 子类prepareRefresh()方法

父类prepareRefresh()方法

2、通知子类刷新内部bean工厂

3、准备bean工厂

4、允许上下文子类对bean工厂进行后置处理

5、调用已注册的BeanFactoryPostProcessors Bean

先调用BeanDefinitionRegistryPostProcessors

再调用BeanFactoryPostProcessor

6、注册BeanPostProcessor

7、初始化信息源

8、注册SimpleApplicationEventMulticaster

9、onRefresh()

10、注册Listener

11、完成beanFactory初始化,初始化所有剩余的单例bean

12、完成刷新


public ConfigurableApplicationContext run(String... args) {
            .... 
	try {
            //本篇内容从本行开始记录  
            refreshContext(context);
           //本篇内容记录到这,后续更新
            ....
        }
	catch (Throwable ex) {
		handleRunFailure(context, ex, exceptionReporters, listeners);
		throw new IllegalStateException(ex);
	}
}

流程分析 

感觉这篇内容会有很多呀!怼它!来看源码。

private void refreshContext(ConfigurableApplicationContext context) {
	refresh(context);
	if (this.registerShutdownHook) {
	    try {
		    context.registerShutdownHook();
	    }
	    catch (AccessControlException ex) {
	    	// Not allowed in some environments.
	    }
	}
}

最终调用父类AbstractApplicationContext的refresh()方法。 

protected void refresh(ApplicationContext applicationContext) {
	Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
	((AbstractApplicationContext) applicationContext).refresh();
}
@Override
public final void refresh() throws BeansException, IllegalStateException {		
    try {
	     super.refresh();
    }
    catch (RuntimeException ex) {
	    stopAndReleaseWebServer();
	    throw ex;
    }
}

 可以看到refresh中的步骤都是单个单个的方法,很方便看,下面一个一个方法讲。

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
	    // 准备刷新
	    prepareRefresh();

	    // 通知子类刷新内部bean工厂
	    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

	    // 准备bean工厂以便在此上下文中使用
	    prepareBeanFactory(beanFactory);

	    try {
	    	// 允许上下文子类中对bean工厂进行后处理
	    	postProcessBeanFactory(beanFactory);

	    	// 在bean创建之前调用BeanFactoryPostProcessors后置处理方法
	    	invokeBeanFactoryPostProcessors(beanFactory);

	    	// 注册BeanPostProcessor
	    	registerBeanPostProcessors(beanFactory);

	    	// 注册DelegatingMessageSource
	    	initMessageSource();

	    	// 注册multicaster
	    	initApplicationEventMulticaster();

	    	// 创建内置的Servlet容器
	    	onRefresh();

	    	// 注册Listener
	    	registerListeners();

	    	// 完成BeanFactory初始化,初始化剩余单例bean
	    	finishBeanFactoryInitialization(beanFactory);

	    	// 发布对应事件
	    	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();
	    }
    }
}

开始之前先把AnnotationConfigServletWebServerApplicationContext类图放这:

SpringBoot(十四)启动流程分析之refreshContext()_第1张图片

1、准备刷新

先调用子类重写的方法,再调用父类方法。还记得前面讲过在创建AnnotationConfigServletWebServerApplicationContext的时候构造方法中实例化了一个ClassPathBeanDefinitionScanner。

@Override
protected void prepareRefresh() {
	this.scanner.clearCache();
	super.prepareRefresh();
}

 子类prepareRefresh()方法

 在其父类ClassPathScanningCandidateComponentProvider中有一个MetadataReaderFactory(接口)工厂对象,判断该对象是否是CachingMetadataReaderFactory这个特定类或者是它的子类的一个实例,返回Boolean值,是就是true,则清除缓存。该类中有个Map,用来缓存每个Spring资源句柄(即每个“.class”文件)的MetadataReader实例。

SpringBoot(十四)启动流程分析之refreshContext()_第2张图片

缓存Map如果是LocalResourceCache(可以看到该类继承了LinkedHashMap),执行的就是LinkedHashMap的clear()方法了;

else如果缓存不为空,就是重新new一个LocalResourceCache。

SpringBoot(十四)启动流程分析之refreshContext()_第3张图片

SpringBoot(十四)启动流程分析之refreshContext()_第4张图片

父类prepareRefresh()方法

protected void prepareRefresh() {
        //系统启动时间
	this.startupDate = System.currentTimeMillis();
        //是否关闭标识,false
	this.closed.set(false);
        //是否活跃标识,true
	this.active.set(true);

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

	// 调用子类GenericWebApplicationContext重写后的方法替换servlet相关属性源
	initPropertySources();

	
	// 这里是验证由ConfigurablePropertyResolver#setRequiredProperties()方法指定的属性,解析为非空值,如果没有设置的话这个方法就不会执行什么操作。
	getEnvironment().validateRequiredProperties();

	// Allow for the collection of early ApplicationEvents,
	// to be published once the multicaster is available...
	this.earlyApplicationEvents = new LinkedHashSet<>();
}

SpringBoot(十四)启动流程分析之refreshContext()_第5张图片

 看下最后这个方法,initServlet属性源,方法注释是这么说的将基于Servlet的StubPropertySource替换为使用给定servletContext和servletConfig对象填充的实例。此方法可以被调用任意次数,但将用相应的实际属性源替换为StubPropertySource一次且仅一次。

看下if判断里的条件,servletContext不为空,source中存在指定name的的属性源,且该属性源要是StubPropertySource的类型或者是其子类。也就是当第一次调用以后,该属性源就被替换成了ServletContextPropertySource和ServletConfigPropertySource,所以之后的调用最后一个判断条件就不会成立了。

public static void initServletPropertySources(MutablePropertySources sources,
			@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {

	Assert.notNull(sources, "'propertySources' must not be null");
        //servletContextInitParams
	String name = StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME;
	if (servletContext != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
		sources.replace(name, new ServletContextPropertySource(name, servletContext));
	}
        //servletConfigInitParams
	name = StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME;
	if (servletConfig != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
		sources.replace(name, new ServletConfigPropertySource(name, servletConfig));
	}
}

 看validateRequiredProperties()方法前,先看下Environment的类图。这里是验证由ConfigurablePropertyResolver#setRequiredProperties()方法指定的属性,解析为非空值,如果没有设置的话这个方法就不会执行什么操作,所以这里就略过了。SpringBoot(十四)启动流程分析之refreshContext()_第6张图片

方法最后new了一个LinkedHashSet,收集早期事件,如果multicaster 有用就会广播事件。

prepareRefresh()就执行完了。

2、通知子类刷新内部bean工厂

 可以看到refreshBeanFactory()方法上的注释说的,什么都不做:我们拥有一个内部beanfactory,并依靠调用方通过我们的公共方法(或beanfactory)注册bean。

前面介绍GenericApplicationContext说了与每次刷新创建新的内部beanfactory实例的其他applicationContext实现不同,此上下文的内部beanfactory从一开始就可用,以便能够在其上注册bean定义。只能调用一次refresh()。

所以在该方法内只设置了SerializationId,该id是在准备应用上下文时调用ContextIdApplicationContextInitializer时设置的id,在setSerializationId方法中,使用id做key,new了一个弱引用对象为value,添加到了serializableFactories中,DefaultListableBeanFactory为被弱引用对象;如果需要,可以通过id得到引用对象,在通过get()方法得到DefaultListableBeanFactory对象。

SpringBoot(十四)启动流程分析之refreshContext()_第7张图片

 SpringBoot(十四)启动流程分析之refreshContext()_第8张图片

3、准备bean工厂

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	//通知内部bean工厂使用上下文的类加载器
	beanFactory.setBeanClassLoader(getClassLoader());
        //为bean定义值中的表达式指定解析策略,即解析el表达式,默认"#{"开头,"}"结尾
	beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        //在这里new了一个资源编辑注册器ResourceEditorRegistrar,该类实现了PropertyEditorRegistrar接口
        //作用是使用以下资源编辑器去填充给的的注册表:ResourceEditor、InputStreamEditor、InputSourceEditor、FileEditor、Urleditor、UriEditor、ClassEditor、ClassArrayEditor。
        //如果给的注册表是PropertyEditorRegistrySupport类型,编辑器交由该类管理
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

	// 向BeanPostProcessor的List中添加一个ApplicationContextAwareProcessor,参数是上下文
        //该类作用是将上下文传递给实现environmentaware、embeddedValueResolveraware、resourceLoaderware、applicationEventPublisheraware、messageSourceAware或applicationContextaware接口的bean。
	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);

	// 该BeanPostProcessor检测那些实现了ApplicationListener接口的bean,在它们创建时初始化之后,将它们添加到应用上下文的事件多播器上
        //并在这些ApplicationListener bean销毁之前,将它们从应用上下文的事件多播器上移除。
	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.
        //注册默认environment bean,如果beanfactory不存在environment 
	if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
	}
        //systemProperties 同上
	if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
	}
        //systemEnvironment 同上
	if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
	}
}

4、允许上下文子类对bean工厂进行后置处理

basePackages和annotatedClasses都为空。跳过

//AnnotationConfigEmbeddedWebApplicationContext.java
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	super.postProcessBeanFactory(beanFactory);
	if (this.basePackages != null && this.basePackages.length > 0) {
		this.scanner.scan(this.basePackages);
	}
	if (!this.annotatedClasses.isEmpty()) {
		this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
	}
}

 注册了一个WebApplicationContextServletContextAwareProcessor。并将ServletContextAware添加到忽略的集合中。再注册web相关作用域bean。

//ServletWebServerApplicationContext.java
/**
* 注册 ServletContextAwareProcessor.
* @see ServletContextAwareProcessor
*/
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	beanFactory.addBeanPostProcessor(
			new WebApplicationContextServletContextAwareProcessor(this));
	beanFactory.ignoreDependencyInterface(ServletContextAware.class);
	registerWebApplicationScopes();
}
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
		registerWebApplicationScopes(beanFactory, null);
	}

/**
* Register web-specific scopes ("request", "session", "globalSession", "application")
* with the given BeanFactory, as used by the WebApplicationContext.
* @param beanFactory the BeanFactory to configure
* @param sc the ServletContext that we're running within
*/
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);
	}
        //注册ServletRequest的工厂bean
	beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
        //注册ServletResponse的工厂bean
	beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
        //注册HttpSession的工厂bean
	beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
        //注册WebRequest的工厂bean
	beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
	if (jsfPresent) {
		FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
	}
}

5、调用已注册的BeanFactoryPostProcessors Bean

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        //这里是委托给了PostProcessorRegistrationDelegate去执行
	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()));
	}
}

 在所有常规bean初始化之前委托PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()去调用BeanFactoryPostProcessors,根据实现BeanDefinitionRegistryPostProcessors ,PriorityOrdered,Ordered接口和其他进行排序,如果有BeanDefinitionRegistryPostProcessors的话,将先调用BeanDefinitionRegistryPostProcessors。这里最开始得到的BeanFactoryPostProcessor有如下三个。

SpringBoot(十四)启动流程分析之refreshContext()_第9张图片

先调用BeanDefinitionRegistryPostProcessors

这是在准备上下文调用initializers的时候添加的三个后置处理类,其中这两个类实现了BeanDefinitionRegistryPostProcessors,将会先执行:

  1. CachingMetadataReaderFactoryPostProcessor
  2. ConfigurationWarningsPostProcessor

PropertySourceOrderingPostProcessor实现BeanFactoryPostProcessor接口,暂时放到List中。再接下来

首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessors。

在创建上下文的时候是注册一个ConfigurationClassPostProcessor,该类实现了PriorityOrdered

第二步:调用实现Ordered的BeanDefinitionRegistryPostProcessors。

最后,调用所有其他BeanDefinitionRegistryPostProcessors。

再调用BeanFactoryPostProcessor

调用完BeanDefinitionRegistryPostProcessors,就开始调用BeanFactoryPostProcessor,同样会根据PriorityOrdered、Ordered进行排序进行先后调用。

SpringBoot(十四)启动流程分析之refreshContext()_第10张图片

首先,调用实现PriorityOrdered的BeanFactoryPostProcessor。

PropertySourcesPlaceholderConfigurer

接下来,调用实现Ordered的BeanFactoryPostProcessor。

最后,调用所有其他BeanFactoryPostProcessor。

SpringBoot(十四)启动流程分析之refreshContext()_第11张图片

最后,清除缓存的合并bean定义,因为后处理器可能修改了原始元数据,例如替换值中的占位符…

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

	// Invoke BeanDefinitionRegistryPostProcessors first, if any.
        //防止重复调用
	Set processedBeans = new HashSet<>();
        //判断beanFactory是否为BeanDefinitionRegistry对像或是其子类对象
	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                //用来存放BeanFactoryPostProcessor类型的实例对象
		List regularPostProcessors = new ArrayList<>();
                //用来存放BeanDefinitionRegistryPostProcessor类型的实例对象
		List registryProcessors = new ArrayList<>();
                //循环最初得到的BeanFactoryPostProcessor List,优先执行postProcessBeanDefinitionRegistry()方法
		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                        //判断postProcessor 是否为BeanDefinitionRegistry对像或是其子类对线
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                                //是就转型,调用postProcessBeanDefinitionRegistry()方法
				BeanDefinitionRegistryPostProcessor registryProcessor =
						(BeanDefinitionRegistryPostProcessor) postProcessor;
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
                                //添加到对应List中
				registryProcessors.add(registryProcessor);
			}
			else {
                                //如果不是BeanDefinitionRegistry对像或是其子类对象,添加到regularPostProcessors中
				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.
                //存放当前调用的BeanDefinitionRegistryPostProcessor对象
		List currentRegistryProcessors = new ArrayList<>();

		    // 首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessors
                //根据类型得到beanName
		String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                //遍历beanName
		for (String ppName : postProcessorNames) {
                        //判断是否实现了PriorityOrdered接口
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                            //是则添加到currentRegistryProcessors中
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);
			}
		}
                //排序
		sortPostProcessors(currentRegistryProcessors, beanFactory);
                //将currentRegistryProcessors中的实例对象添加到registryProcessors中
		registryProcessors.addAll(currentRegistryProcessors);
                //循环调用postProcessBeanDefinitionRegistry()方法
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                //清空currentRegistryProcessors
		currentRegistryProcessors.clear();

		    // 调用实现Ordered接口的BeanDefinitionRegistryPostProcessors。流程跟上面一样了
		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();

		    // 最后调用所有其他BeanDefinitionRegistryPostProcessors。
		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();
		}

		    // 现在, 调用BeanDefinitionRegistryPostProcessors的postProcessBeanFactory()方法
		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 priorityOrderedPostProcessors = new ArrayList<>();
	List orderedPostProcessorNames = new ArrayList<>();
	List 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 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 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();
}

整理一下调用顺序:

1、首先从BeanFactory得到List集合。

2、判断是否属于BeanDefinitionRegistryPostProcessors,是则先调用postProcessBeanDefinitionRegistry()方法,这里调用的有:

  • CachingMetadataReaderFactoryPostProcessor
  • ConfigurationWarningsPostProcessor

3、然后调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry()方法,这里调用的有:

  • ConfigurationClassPostProcessor

4、调用实现Ordered的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry(),这里没有。

5、调用所有其他BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry(),这里也没有。

6、在调用BeanDefinitionRegistryPostProcessors的postProcessBeanFactory()方法,这里调用的有:

  • CachingMetadataReaderFactoryPostProcessor
  • ConfigurationWarningsPostProcessor
  • ConfigurationClassPostProcessor
  • PropertySourceOrderingPostProcessor

7、调用实现PriorityOrderedBeanFactoryPostProcessorpostProcessBeanFactory()方法,这里调用的有:

  • PropertySourcesPlaceholderConfigurer

8、调用实现Ordered的BeanFactoryPostProcessor的postProcessBeanFactory()方法,这里没有。

9、调用所有其他BeanFactoryPostProcessor的postProcessBeanFactory()方法,这里调用的有:

  • EventListenerMethodProcessor
  • ConfigurationBeanFactoryMetadata
  • PreserveErrorControllerTargetClassPostProcessor

10、最后,清除缓存的合并bean定义,因为后处理器可能修改了原始元数据,例如替换值中的占位符…

postProcessBeanDefinitionRegistry()方法  
CachingMetadataReaderFactoryPostProcessor 注册了一个SharedMetadataReaderFactoryBean,并配置到ConfigurationClassPostProcessor
ConfigurationWarningsPostProcessor 检查@ComponentScan设置的包是否存在问题,并打印日志
ConfigurationClassPostProcessor 处理@Configuration配置类,这里的内容不止是我简单的这一句话,里面还有很多东西
postProcessBeanFactory()方法  
CachingMetadataReaderFactoryPostProcessor
ConfigurationWarningsPostProcessor
ConfigurationClassPostProcessor 通过cglib 增强的子类替换候选的full配置类,是否为full配置类的具体判断逻辑见

ConfigurationClassUtils.isFullConfigurationCandidate()方法

PropertySourceOrderingPostProcessor  
EventListenerMethodProcessor 通过beanFactory得到DefaultEventListenerFactory并设置,该类实现了SmartInitializingSingleton接口,重写了afterSingletonsInstantiated方法,会在所有单实例bean实例化之后执行,就是后面的finishBeanFactoryInitialization()方法会进行回调,在afterSingletonsInstantiated方法中会处理带有@EventListener注解的方法,用postProcessBeanFactory()设置的eventListenerFactories创建listener,添加到上下文
ConfigurationBeanFactoryMetadata 在bean工厂初始化期间存储@bean定义元数据
PreserveErrorControllerTargetClassPostProcessor  

6、注册BeanPostProcessor

这里同样根据实现priorityordered、ordered和其他对beanPostprocessor进行分类。

首先,注册实现PriorityOrdered的BeanPostProcessor:

  • ConfigurationPropertiesBindingPostProcessor
  • CommonAnnotationBeanPostProcessor
  • AutowiredAnnotationBeanPostProcessor

接下来,注册实现Ordered的beanPostProcessor:

  • MethodValidationPostProcessor

现在,注册所有常规的beanPostProcessor:

  • WebServerFactoryCustomizerBeanPostProcessor
  • ErrorPageRegistrarBeanPostProcessor

最后,重新注册所有内部BeanPostProcessor。

  • AutowiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor

在后面再注册了ApplicationListenerDetector。

这里流程跟上面调用BeanFactoryPostProcessor是差不多的,自己看吧。

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
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 priorityOrderedPostProcessors = new ArrayList<>();
	List internalPostProcessors = new ArrayList<>();
	List orderedPostProcessorNames = new ArrayList<>();
	List 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.
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// Next, register the BeanPostProcessors that implement Ordered.
	List orderedPostProcessors = new ArrayList<>();
	for (String ppName : orderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		orderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

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

	// Finally, re-register all internal BeanPostProcessors.
	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).
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

在哪里应用BeanPostProcessor呢?

简单说一下,doGetBean方法----getSingleton----createBean----doCreateBean----initializeBean。会在bean初始化之前应用。

 SpringBoot(十四)启动流程分析之refreshContext()_第12张图片

SpringBoot(十四)启动流程分析之refreshContext()_第13张图片

SpringBoot(十四)启动流程分析之refreshContext()_第14张图片

7、初始化信息源

这里就是注册一个DelegatingMessageSource。

protected void initMessageSource() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
		this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
		// Make MessageSource aware of parent MessageSource.
		if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
			HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
			if (hms.getParentMessageSource() == null) {
				// Only set parent context as parent MessageSource if no parent MessageSource
				// registered already.
				hms.setParentMessageSource(getInternalParentMessageSource());
			}
		}
		if (logger.isTraceEnabled()) {
			logger.trace("Using MessageSource [" + this.messageSource + "]");
		}
	}
	else {
		// Use empty MessageSource to be able to accept getMessage calls.
		DelegatingMessageSource dms = new DelegatingMessageSource();
		dms.setParentMessageSource(getInternalParentMessageSource());
		this.messageSource = dms;
		beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
		if (logger.isTraceEnabled()) {
			logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
		}
	}
}

8、注册SimpleApplicationEventMulticaster

注册一个SimpleApplicationEventMulticaster,不多说,前面说了。

protected void initApplicationEventMulticaster() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
                //applicationEventMulticaster
		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() + "]");
		}
	}
}

9、onRefresh()

初始化特定上下文子类中的其他特殊bean。一个模板方法,不同的Spring容器做不同的事情。在这里会调用createWebServer()去创建内置的Servlet容器。创建Servlet容器的过程中做的事情就比较多了。不做详细介绍。

最开始入门就介绍了Spring Boot支持以下嵌入式servlet容器:
 

Name Servlet Version

Tomcat 9.0

4.0

Jetty 9.4

3.1

Undertow 2.0

4.0

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

默认的是Tomcat,其中customizeConnector()方法就是定制内嵌的Tomcat ,如果你实现了TomcatConnectorCustomizer接口并重写了customize方法。

SpringBoot(十四)启动流程分析之refreshContext()_第15张图片

下面的日志是不是很熟悉了。 

SpringBoot(十四)启动流程分析之refreshContext()_第16张图片

10、注册Listener

protected void registerListeners() {
	// 得到多播器,添加Listener
	for (ApplicationListener listener : getApplicationListeners()) {
		getApplicationEventMulticaster().addApplicationListener(listener);
	}

	// 这里流程跟上面一样了
	String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
	for (String listenerBeanName : listenerBeanNames) {
		getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
	}

	// 发布早期事件
	Set earlyEventsToProcess = this.earlyApplicationEvents;
	this.earlyApplicationEvents = null;
	if (earlyEventsToProcess != null) {
		for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
			getApplicationEventMulticaster().multicastEvent(earlyEvent);
		}
	}
}

11、完成beanFactory初始化,初始化所有剩余的单例bean

SpringBoot(十四)启动流程分析之refreshContext()_第17张图片

具体的Bean初始化流程参考:https://www.cnblogs.com/xrq730/p/6361578.html

会在这一步调用SmartInitializingSingleton接口的afterSingletonsInstantiated()方法。

12、完成刷新

发布ContextRefreshedEvent,这里发布事件调用的是AbstractApplicationContext的publishEvent()方法,不过最终发布事件还是调用的多播器EventMulticaster的multicastEvent()方法,也就是前面说过的事件发布方法。

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
	Assert.notNull(event, "Event must not be null");
	// Decorate event as an ApplicationEvent if necessary
	ApplicationEvent applicationEvent;
	if (event instanceof ApplicationEvent) {
		applicationEvent = (ApplicationEvent) event;
	}
	else {
		applicationEvent = new PayloadApplicationEvent<>(this, event);
		if (eventType == null) {
			eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
		}
	}
	// Multicast right now if possible - or lazily once the multicaster is initialized
	if (this.earlyApplicationEvents != null) {
		this.earlyApplicationEvents.add(applicationEvent);
	}
	else {
		getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
	}
	// Publish event via parent context as well...
	if (this.parent != null) {
		if (this.parent instanceof AbstractApplicationContext) {
			((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
		}
		else {
			this.parent.publishEvent(event);
		}
	}
}

SpringBoot(十四)启动流程分析之refreshContext()_第18张图片

 

DelegatingApplicationListener:没做事

ConditionEvaluationReportListener:日志自动配置报告

ClearCachesApplicationListener:在加载上下文后清除缓存。

SharedMetadataReaderFactoryBean:删除所有缓存的类元数据。

ResourceUrlProvider

最后启动Tomcat,发布ServletWebServerInitializedEvent事件。

SpringBoot(十四)启动流程分析之refreshContext()_第19张图片

SpringApplicationAdminMXBeanRegistrar:更改embeddedWebApplication为true,嵌入式web程序。

DelegatingApplicationListener:无 

ServerPortInfoApplicationContextInitializer:这个前面有提过的,设置了webserver实际监听的端口值,如果该事件的WebServerApplicationContext具有NameSpace,则使用它来构造属性名,否则使用缺省值server。

就到这里,后面都是清理缓存,感觉身体被掏空......

 

你可能感兴趣的:(springboot,SpringBoot学习记录)