Springboot2.20 启动源码分析

341 阅读8分钟

Spring boot 源码

知识储备

Spring Factories机制

org.springframework.core.io.support.SpringFactoriesLoader 的关键代码:

public final class SpringFactoriesLoader {
	
	// 配置文件的路径,spring boot jar包下的文件
	public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
	
	......
	
	// 注意这里会加载多个jar中的“META-INF/spring.factories”文件
	public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
		String factoryTypeName = factoryType.getName();
		return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
	}

    // 这里只是找到某个接口配置在spring.factories下的实现类,实例化一般在调用的地方通过反射实现
	private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
		MultiValueMap<String, String> result = cache.get(classLoader);
		if (result != null) {
			return result;
		}

		try {
			Enumeration<URL> urls = (classLoader != null ?
					classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
					ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
			result = new LinkedMultiValueMap<>();
			while (urls.hasMoreElements()) {
				URL url = urls.nextElement();
				UrlResource resource = new UrlResource(url);
				Properties properties = PropertiesLoaderUtils.loadProperties(resource);
				for (Map.Entry<?, ?> entry : properties.entrySet()) {
					String factoryTypeName = ((String) entry.getKey()).trim();
					for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
						result.add(factoryTypeName, factoryImplementationName.trim());
					}
				}
			}
			cache.put(classLoader, result);
			return result;
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Unable to load factories from location [" +
					FACTORIES_RESOURCE_LOCATION + "]", ex);
		}
	}
	
	......

}

eg:例如spring-boot jar包下的META-INF/spring.factories 文件里以key=value,value的形式存在,一般key是某个接口,value就是接口的实现列表

org.springframework.boot.BeanPostProcessor=\
org.springframework.boot.context.event.EventPublishingRunListener

SpringBoot 启动入口

@SpringBootApplication
public class SbootMain {

    public static void main(String[] args) {
        // 传入启动类和启动参数
        SpringApplication.run(SbootMain.class, args);
    }
}

org.springframework.boot.SpringApplication 实例化部分代码

public class SpringApplication {
    ······
    
     public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
		return new SpringApplication(primarySources).run(args);
	}

    public SpringApplication(Class<?>... primarySources) {
            this(null, primarySources);
        }

    // 实例化SpringApplication,启动类作为初始资源传入
    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
            this.resourceLoader = resourceLoader;
            Assert.notNull(primarySources, "PrimarySources must not be null");
        	// 把启动类作为作为资源放入初始资源里
            this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
        	// 判断容器启动的方式,默认SERVLET 即启动一个Servlet容器
            this.webApplicationType = WebApplicationType.deduceFromClasspath();
        	// 加载并实例化classpath下jar包中的spring.factories中的ApplicationContextInitializer实现
            setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
        	// 加载并实例化classpath下jar包中的spring.factories中的ApplicationListener实现
            setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        	// 通过获取当前调用栈,找到入口方法main所在的类,并将其复制给SpringApplication对象的成员变量mainApplicationClass
            this.mainApplicationClass = deduceMainApplicationClass();
        }
    
    private Class<?> deduceMainApplicationClass() {
		try {
            //通过调用栈找到main方法的类
			StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
			for (StackTraceElement stackTraceElement : stackTrace) {
				if ("main".equals(stackTraceElement.getMethodName())) {
					return Class.forName(stackTraceElement.getClassName());
				}
			}
		}
		catch (ClassNotFoundException ex) {
			// Swallow and continue
		}
		return null;
	}
        
	······
}

ApplicationContextInitializer是一个可以用来初始化ApplicationContext的接口

public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {

	void initialize(C applicationContext);

}

spring boot 启动加载的ApplicationContextInitializer实现
org.springframework.boot.context.config.DelegatingApplicationContextInitializer
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer
org.springframework.boot.context.ContextIdApplicationContextInitializer
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

ApplicationListener 是用来监听spring容器启动各阶段做相应初始化的接口

@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

	/**
	 * Handle an application event.
	 * @param event the event to respond to
	 */
	void onApplicationEvent(E event);

}
ApplicationEvent 有很多实现代表着不同的事件,在容器启动过程的不同阶段会分别触发这些事件,监听器针对不同的事件作出相应的处理,后续分析中会具体讲述。

spring boot 启动过程中加载的ApplicationListener实现
org.springframework.boot.context.config.ConfigFileApplicationListener
org.springframework.boot.context.config.AnsiOutputApplicationListener
org.springframework.boot.context.logging.LoggingApplicationListener
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener
org.springframework.boot.autoconfigure.BackgroundPreinitializer
org.springframework.boot.context.config.DelegatingApplicationListener
org.springframework.boot.builder.ParentContextCloserApplicationListener
org.springframework.boot.ClearCachesApplicationListener
org.springframework.boot.context.FileEncodingApplicationListener
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

run方法

org.springframework.boot.SpringApplication#run 关键部分代码,下列解释中的编号后续用对应部分的关键代码

SpringApplication {
    
    ……
    
	public ConfigurableApplicationContext run(String... args) {
        // StopWatch是来自org.springframework.util的工具类,可以用来方便的记录程序的运行时间。
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
        
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        // 设置headless模式,就是设置系统属性java.awt.headless,开发的是服务器程序,一般运行在没有显示器和键盘的环境。
		configureHeadlessProperty();
        // 1. 通过SpringFactoriesLoader加载SpringApplicationRunListener接口的实现,springboot 启动时有EventPublishingRunListener实现,通过反射实例化,构造方法中传入SpringApplication实例和启动参数,这里运用了观察者模式来触发之前注册的监听器
		SpringApplicationRunListeners listeners = getRunListeners(args);
        // 触发ApplicationStartingEvent事件
		listeners.starting();
		try {
            // 2. 可以看到是把main函数的args参数当做一个PropertySource来解析。我们的例子中,args的长度为0,所以这里创建的DefaultApplicationArguments也没有实际的内容。
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            // 3. 创建并配置ApplicationConext的Environment
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			configureIgnoreBeanInfo(environment);
            // 打印banner
			Banner printedBanner = printBanner(environment);
            // 4. 创建ApplicationContext容器,web环境创建AnnotationConfigServletWebServerApplicationContext
			context = createApplicationContext();
            //加载启动异常分析器
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
            // 5. 刷新应用上下文前的准备阶段
			prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            // 刷新spring 容器,spring容器启动核心
			refreshContext(context);
            // 空实现
			afterRefresh(context, applicationArguments);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
			}
            // 触发ApplicationStartedEvent事件
			listeners.started(context);
            //在某些情况下,我们希望在容器bean加载完成后执行一些操作,会实现ApplicationRunner或者CommandLineRunner接口后置操作,就是在容器完成刷新后,依次调用注册的Runners,还可以通过@Order注解设置各runner的执行顺序。
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
            // 触发容器启动失败ApplicationFailedEvent事件
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}

		try {
            // 触发ApplicationReadyEvent事件
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}
   	……
}

AnnotationConfigServletWebServerApplicationContext的继承关系

1. 监听器

org.springframework.boot.SpringApplicationRunListener 接口,主要实现org.springframework.boot.context.event.EventPublishingRunListener,里面包含了SpringApplication实例化时加载的ApplicationListener 监听器,通过EventPublishingRunListener触发之前的监听器

public interface SpringApplicationRunListener {

	// 第一次启动的时候,用来初始化,触发ApplicationStartingEvent事件
	default void starting() {
	}

	// 环境准备就绪之后和ApplicationContext就绪之前触发ApplicationEnvironmentPreparedEvent事件
	default void environmentPrepared(ConfigurableEnvironment environment) {
	}

    // ApplicationContext 创建就绪之后,资源加载之前触发ApplicationContextInitializedEvent事件
	default void contextPrepared(ConfigurableApplicationContext context) {
	}

    // ApplicationContext 资源加载完之后,refreshed之前触发ApplicationPreparedEvent事件
	default void contextLoaded(ConfigurableApplicationContext context) {
	}

    // ApplicationContext refreshed之后,CommandLineRunners、ApplicationRunner调用之前触发ApplicationStartedEvent事件
	default void started(ConfigurableApplicationContext context) {
	}

    // ApplicationContext refreshed之后和SpringApplication run方法完成之后触发ApplicationReadyEvent事件
	default void running(ConfigurableApplicationContext context) {
	}

    // 容器启动失败触发ApplicationFailedEvent事件
	default void failed(ConfigurableApplicationContext context, Throwable exception) {
	}

}
2. 参数封装

org.springframework.boot.DefaultApplicationArguments 封装main方法的启动参数

	public DefaultApplicationArguments(String... args) {
		Assert.notNull(args, "Args must not be null");
		this.source = new Source(args);
		this.args = args;
	}

	//org.springframework.boot.DefaultApplicationArguments.Source 
	Source(String[] args) {
			super(args);
		}
	//org.springframework.core.env.SimpleCommandLinePropertySource
	public SimpleCommandLinePropertySource(String... args) {
		super(new SimpleCommandLineArgsParser().parse(args));
	}
3. 配置环境

prepareEnvironmen方法

创建并配置ApplicationConext的Environment,org.springframework.boot.SpringApplication,SpringApplication的Environment代表着程序运行的环境,主要包含了两种信息,一种是profiles,用来描述哪些bean definitions是可用的;一种是properties,用来描述系统的配置,其来源可能是配置文件、JVM属性文件、操作系统环境变量等等。

SpringApplication{
    
    ……
    
    private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
			ApplicationArguments applicationArguments) {
		// 创建并配置Environment,这里根据之前配置的webApplicationType创建StandardServletEnvironment
		ConfigurableEnvironment environment = getOrCreateEnvironment();
        // 配置上一步获取的Environment对象
		configureEnvironment(environment, applicationArguments.getSourceArgs());
		ConfigurationPropertySources.attach(environment);
        // 触发监听器ApplicationEnvironmentPreparedEvent事件
		listeners.environmentPrepared(environment);
		bindToSpringApplication(environment);
		if (!this.isCustomEnvironment) {
			environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
					deduceEnvironmentClass());
		}
		ConfigurationPropertySources.attach(environment);
		return environment;
	}
    
    ……
    
    protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
		if (this.addConversionService) {
			ConversionService conversionService = ApplicationConversionService.getSharedInstance();
			environment.setConversionService((ConfigurableConversionService) conversionService);
		}
		configurePropertySources(environment, args);
		configureProfiles(environment, args);
	}
    
    // 首先查看SpringApplication对象的成员变量defaultProperties,如果该变量非null且内容非空,则将其加入到Environment的PropertySource列表的最后。然后查看SpringApplication对象的成员变量addCommandLineProperties和main函数的参数args,如果设置了addCommandLineProperties=true,且args个数大于0,那么就构造一个由main函数的参数组成的PropertySource放到Environment的PropertySource列表的最前面(这就能保证,我们通过main函数的参数来做的配置是最优先的,可以覆盖其他配置)
    protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
		MutablePropertySources sources = environment.getPropertySources();
		if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) {
			sources.addLast(new MapPropertySource("defaultProperties", this.defaultProperties));
		}
		if (this.addCommandLineProperties && args.length > 0) {
			String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME;
			if (sources.contains(name)) {
				PropertySource<?> source = sources.get(name);
				CompositePropertySource composite = new CompositePropertySource(name);
				composite.addPropertySource(
						new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args));
				composite.addPropertySource(source);
				sources.replace(name, composite);
			}
			else {
				sources.addFirst(new SimpleCommandLinePropertySource(args));
			}
		}
	}
    
    // 首先会读取Properties中key为spring.profiles.active的配置项,配置到Environment,然后再将SpringApplication对象的成员变量additionalProfiles加入到Environment的active profiles配置中。
    protected void configureProfiles(ConfigurableEnvironment environment, String[] args) {
		Set<String> profiles = new LinkedHashSet<>(this.additionalProfiles);
		profiles.addAll(Arrays.asList(environment.getActiveProfiles()));
		environment.setActiveProfiles(StringUtils.toStringArray(profiles));
	}
        
    
    ……
}

4. 创建容器

createApplicationContext方法

创建ApplicationContext容器

SpringApplication{
	……
    
   /**
	 * The class name of application context that will be used by default for non-web
	 * environments.
	 */
	public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."
			+ "annotation.AnnotationConfigApplicationContext";

	/**
	 * The class name of application context that will be used by default for web
	 * environments.
	 */
	public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
			+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";

	/**
	 * The class name of application context that will be used by default for reactive web
	 * environments.
	 */
	public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
			+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";
    
    ……
	
	protected ConfigurableApplicationContext createApplicationContext() {
		Class<?> contextClass = this.applicationContextClass;
		if (contextClass == null) {
			try {
				switch (this.webApplicationType) {
				case SERVLET:
                    // springboot web 环境创建AnnotationConfigServletWebServerApplicationContext
					contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
					break;
				case REACTIVE:
					contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
					break;
				default:
					contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
				}
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
			}
		}
		return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
	}

	……
}

// org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
AnnotationConfigServletWebServerApplicationContext{
    ……
        
    public AnnotationConfigServletWebServerApplicationContext() {
        // 实例化了一个Bean读取器,并向BeanDefinitionMap中注册spring bean的工厂后置处理器BeanFactoryPostProcessor和spring bean的后置处理器BeanPostProcessor
		this.reader = new AnnotatedBeanDefinitionReader(this);
        // 初始化一个扫描器,这个扫描器在后面扫描包的时候,并没有用到,猜测是Spring为了满足其他的场景而初始化的
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
    
        
   ……
}

// org.springframework.context.annotation.AnnotatedBeanDefinitionReader
AnnotatedBeanDefinitionReader{
    
    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
		this(registry, getOrCreateEnvironment(registry));
	}

	
	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
        // 注册spring bean的工厂后置处理器BeanFactoryPostProcessor和spring bean的后置处理器BeanPostProcessor
        // ConfigurationClassPostProcessor spring bean 工厂后置处理器,解析@Configurable 后续详细讲解
        // AutowiredAnnotationBeanPostProcessor spring bean后置处理器,处理spring bean的自动注入
        // CommonAnnotationBeanPostProcessor 用来处理如@Resource,@PostConstruct等符合JSR-250规范的注解
        // EventListenerMethodProcessor
        // DefaultEventListenerFactory
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}
}
5. 刷新上下文准备

prepareContext 方法

SpringApplication{
    ……
    
    private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
			SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
        // 设置容器环境
		context.setEnvironment(environment);
        // 注册bean name生成器
		postProcessApplicationContext(context);
        // 执行ApplicationContextInitializer
		applyInitializers(context);
        // 触发ApplicationContextInitializedEvent事件
		listeners.contextPrepared(context);
		if (this.logStartupInfo) {
			logStartupInfo(context.getParent() == null);
			logStartupProfileInfo(context);
		}
		// 注册spring boot 特殊的单例bean
		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        // 将main函数中的args参数封装成单例Bean,注册进容器
		beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
        // 将 printedBanner 也封装成单例,注册进容器
		if (printedBanner != null) {
			beanFactory.registerSingleton("springBootBanner", printedBanner);
		}
		if (beanFactory instanceof DefaultListableBeanFactory) {
			((DefaultListableBeanFactory) beanFactory)
					.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		if (this.lazyInitialization) {
            // 注册懒加载工厂后置处理器 BeanFactoryPostProcessor
			context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
		}
		// Load the sources
		Set<Object> sources = getAllSources();
		Assert.notEmpty(sources, "Sources must not be empty");
        // //加载我们的启动类,将启动类注入容器
		load(context, sources.toArray(new Object[0]));
        // 触发ApplicationPreparedEvent事件
		listeners.contextLoaded(context);
	}
    
    ……
}
6. 刷新上下文
BeanPostProcessorSpringApplication{
	……
	
	private void refreshContext(ConfigurableApplicationContext context) {
		refresh(context);
		if (this.registerShutdownHook) {
			try {
				context.registerShutdownHook();
			}
			catch (AccessControlException ex) {
				// Not allowed in some environments.
			}
		}
	}
	
    protected void refresh(ApplicationContext applicationContext) {
		Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
		((AbstractApplicationContext) applicationContext).refresh();
	}
    
	……
}

// org.springframework.context.support.AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
    ……
    
    @Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 刷新前准备,设置启动时间和活动状态
			prepareRefresh();

			// 由子类实现,springboot中由GenericApplicationContext实现,给beanFactory设置序列化id
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 设置容器的classLoader,注册两个bean后置处理器BeanPostProcessor和默认的环境bean
            // 1. ApplicationContextAwareProcessor处理实现了ApplicationContextAware接口的类,回调setApplicationContext()方法
            // 2. ApplicationListenerDetector用来检测ApplicationListener类的,当某个Bean实现了ApplicationListener接口的bean被创建好后,会被加入到监听器列表中
			prepareBeanFactory(beanFactory);

			try {
                //由子类实现,springboot中由GenericApplicationContext实现,如果是Servlet环境则注册一个后置处理器ServletContextAwareProcessor用来处理实现了ServletContextAware接口的bean
				postProcessBeanFactory(beanFactory);

				// 执行所有的BeanFactoryPostProcessor,包括自定义的,以及spring内置的。会先执行实现了BeanDefinitionRegistryPostProcessor接口的类,然后执行BeanFactoryPostProcessor的类
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册并实例化bean的后置处理器
				registerBeanPostProcessors(beanFactory);

				// 初始化MessageSource,用来做消息国际化。在一般项目中不会用到消息国际化
				initMessageSource();

				// 初始化事件广播器,如果容器中存在了名字为applicationEventMulticaster的广播器,则使用该广播器,如果没有,则初始化一个SimpleApplicationEventMulticaster 事件广播器的用途是,发布事件,并且为所发布的时间找到对应的事件监听器。
				initApplicationEventMulticaster();

				// 执行其他的初始化操作,在spring boot web项目里在父类ServletWebServerApplicationContext里初始化嵌入的web服务器
				onRefresh();

				// 这一步会将自定义的listener的bean名称放入到事件广播器中同时还会将早期的ApplicationEvent发布(对于单独的spring工程来说,在此时不会有任何ApplicationEvent发布,但是和springMVC整合时,springMVC会执行onRefresh()方法,在这里会发布事件)
				registerListeners();

				// 	实例化剩余的非懒加载的单例bean(注意:剩余、非懒加载、单例)为什么说是剩余呢?如果开发人员自定义了BeanPosrProcessor,而BeanPostProcessor在前面已经实例化了,所以在这里不会再实例化,因此这里使用剩余一词
				finishBeanFactoryInitialization(beanFactory);

				// 结束refresh,主要干了一件事,就是发布一个事件ContextRefreshEvent,通知大家spring容器refresh结束了。
				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();
			}
		}
	}
        
	……  
}

//org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors 执行spring bean工厂后置处理器BeanFactoryPostProcessor的关键代码
// 注册bean的后置处理器 BeanPostProcessor
PostProcessorRegistrationDelegate{
    ……
        
    public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

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

        //BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,先处理BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry,在处理BeanFactoryPostProcessor#postProcessBeanFactory
        //org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor, org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor, org.springframework.boot.context.config.ConfigFileApplicationListener$PropertySourceOrderingPostProcessor
        //这三个工厂后置处理器是通过ApplicationContextInitializer或者ApplicationListener注册的
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			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);
				}
			}

            //这里不需要初始化FactoryBeans,我们需要保留所有常规bean的未初始化状态,以便让bean工厂后处理程序应用于它们!分离实现了PriorityOrdered, Ordered的工厂后置处理器,排序之后调用
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// BeanDefinitionRegistryPostProcessors 实现了 PriorityOrdered 的工厂后置处理器,这里有个比较重要的工厂后置处理器ConfigurationClassPostProcessor,postProcessBeanDefinitionRegistry()方法进行了@Configuration类的解析,@ComponentScan的扫描,以及@Import注解的处理,详细后续分析
			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();

			// BeanDefinitionRegistryPostProcessors 实现了 Ordered,在springboot 启动debug过程中这里没有处理器
			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();

			//调用所有其他BeanDefinitionRegistryPostProcessor,比如mybatis的MapperScannerConfigurer工厂后置处理器就是这里执行的,配置和扫描mybatis相关的bean
			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();
			}

			// 现在,调用到目前为止处理的所有处理器的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);

        // 分离出分别实现了PriorityOrdered和Ordered接口的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// 在上面处理BeanDefinitionRegistryPostProcessor的时候执行过的跳过
			}
			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);
			}
		}

		// 先执行实现了PriorityOrdered 接口的BeanFactoryPostProcessor,这里有个重要的后置处理PropertySourcesPlaceholderConfigurer,允许用 Properties 文件中的属性来定义应用上下文(配置文件或者注解)
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// 再执行实现了Ordered接口的BeanFactoryPostProcessor,这里也有一个重要的后置处理器ConfigurationPropertiesBeanDefinitionValidator,属性绑定后置处理器
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// 最后是其他的BeanFactoryPostProcessor,这里也有两个处理器
        // 1. EventListenerMethodProcessor,用来将应用中每个使用@EventListener注解定义的事件监听方法变成一个ApplicationListener实例注册到容器
        // 2. ErrorMvcAutoConfiguration$PreserveErrorControllerTargetClassPostProcessor,它的目的是为ErrorController bean的定义设置属性preserveTargetClass:true,从而确保ErrorController bean如果有代理对象的话代理对象总是代理在类上而不是接口上。
		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();
	}
    
    ……
        
    public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

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

		// 注册BeanPostProcessorChecker,在BeanPostProcessor实例化期间创建一个bean时,即当一个bean不适合由所有BeanPostProcessor处理时,记录一条信息消息。
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // 分离分别实现了PriorityOrdered和Ordered,还有其他BeanPostProcessor
		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);
			}
		}

		// 先注册和实例化实现了PriorityOrdered接口的BeanPostProcessor,这里有三个重要的处理器org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor, org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 再注册和实例化实现了Ordered接口的BeanPostProcessor,MethodValidationPostProcessor, DataSourceInitializerPostProcessor, AnnotationAwareAspectJAutoProxyCreator, PersistenceExceptionTranslationPostProcessor
		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);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor, org.springframework.boot.web.server.ErrorPageRegistrarBeanPostProcessor, org.springframework.data.web.config.ProjectingArgumentResolverRegistrar$ProjectingArgumentResolverBeanPostProcessor
		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);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// 最后,重新注册所有内部beanPostProcessor,放到后置处理器的末端
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// 重新注册后处理程序,以检测内部bean作为应用程序侦听器,将其移动到处理器链的末端(用于获取代理等)。
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}
}
7. 实例化bean

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

DefaultListableBeanFactory{
	……

	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...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					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 {
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		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();
				}
			}
		}
	}
	
	……
}