Spring Boot启动-6-run方法之AbstractApplicationContext#refresh()

本文源码基于Spring 5.2.7
Spring中,容器的填充全靠org.springframework.context.support.AbstractApplicationContext#refresh()方法,这个方法的每一步都是值得分析的,这每一步都会分为一篇或多篇文章来解析,这里对这些步骤作一个整体说明。
Spring的核心能力就是作为控制反转容器使用,通过名称可以看出,这个方法是用来刷新容器的,可想而知这个方法包含了Spring核心能力,包括AOP的处理过程都在这里。

作为一个服务框架,Spring提供了强大的扩展能力,Spring的设计是定义很多post processor接口,启动时,会按照次序执行这些post processor,这样,用户可以自行在启动的不同时间节点,扩展自己的功能,这种设计方式就是模板方法。

org.springframework.context.support.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.
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			invokeBeanFactoryPostProcessors(beanFactory);

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

			// Initialize message source for this context.
			initMessageSource();

			// Initialize event multicaster for this context.
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			onRefresh();

			// Check for listener beans and register them.
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			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();
		}
	}
}

一、postProcessBeanFactory()

// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);

先看这个方法,这句话的意思就是调用AbstractApplicationContext的子类的postProcessBeanFactory()方法,这个描述容易和调用BeanFactoryPostProcessor类这个过程混淆,这个模板方法是留给Spring内部扩展使用的,开发者无法介入。
org.springframework.context.support.AbstractApplicationContext#postProcessBeanFactory()
在application context标准初始化完成后修改它内部的bean factory。此时所有的bean definitions已经被加载,但是bean都还没有初始化。这样的话就能够在某个ApplicationContext的实现类中注册特定的BeanPostProcessors。
AbstractApplicationContext中的这个方法是个空方法,留给子类去实现。

/**
 * Modify the application context's internal bean factory after its standard
 * initialization. All bean definitions will have been loaded, but no beans
 * will have been instantiated yet. This allows for registering special
 * BeanPostProcessors etc in certain ApplicationContext implementations.
 * @param beanFactory the bean factory used by the application context
 */
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

二、invokeBeanFactoryPostProcessors()

// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

然后是invokeBeanFactoryPostProcessors(),这个方法的作用是调用在容器注册的BeanFactoryPostProcessor类方法,BeanFactoryPostProcessor是留给Spring内部以及开发者扩展的接口,前提是要注册到容器中来。 
 

这里定义了2种类型的post processor,分别是
org.springframework.beans.factory.config.BeanFactoryPostProcessor
org.springframework.beans.factory.config.BeanPostProcessor
开发者可以定义自己的post processor,且执行顺序是先执行BeanFactoryPostProcessor后执行BeanPostProcessor,同一种类型的post processor可以定义优先级来控制执行顺序,这样开发者就能在启动时扩展自己的功能。

你可能感兴趣的:(#,Spring原理篇,spring,boot,后端,java)