【Spring boot】启动过程源码分析( 三 )

创建引导启动器private DefaultBootstrapContext createBootstrapContext() {// 构建一个DefaultBootstrapContext对象,这个对象是2.4.0之后才会有!DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();// 利用bootstrapRegistryInitializers初始化bootstrapContext 。可以在spring.factories中设置bootstrapRegistryInitializersthis.bootstrapRegistryInitializers.forEach((initializer) -> initializer.initialize(bootstrapContext));return bootstrapContext;}准备environmentprivate ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {// Create and configure the environment这句话是源码中本身的注释!// 创建ApplicationServletEnvironment 。ConfigurableEnvironment environment = getOrCreateEnvironment();// 添加SimpleCommandLinePropertySource放在首位configureEnvironment(environment, applicationArguments.getSourceArgs());// 把所有的PropertySource封装为ConfigurationPropertySourcesPropertySource,然后添加到environment中,放在首位!ConfigurationPropertySources.attach(environment);// 发布ApplicationEnvironmentPreparedEvent(应用Environment准备完成)事件,表示环境已经准备好了 。默认EnvironmentPostProcessorApplicationListener去处理这个事件!listeners.environmentPrepared(bootstrapContext, environment);// 把DefaultProperties放到最后DefaultPropertiesPropertySource.moveToEnd(environment);// 环境中spring.main.environment-prefix参数校验Assert.state(!environment.containsProperty("spring.main.environment-prefix"), "Environment prefix cannot be set via properties.");// 环境中spring.main参数校验bindToSpringApplication(environment);if (!this.isCustomEnvironment) {environment = convertEnvironment(environment);}ConfigurationPropertySources.attach(environment);return environment;}准备spring容器的操作private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {// 设置环境变量到spring容器context.setEnvironment(environment);// 设置在SpringApplication上的BeanNameGenerator、resourceLoader设置到spring容器中postProcessApplicationContext(context);// 使用ApplicationContextInitializer初始化spring容器applyInitializers(context);// 容器初始化完成,发布ApplicationContextInitializedEvent事件listeners.contextPrepared(context);// 关闭引导的容器bootstrapContext.close(context);if (this.logStartupInfo) {logStartupInfo(context.getParent() == null);logStartupProfileInfo(context);}// 注册一些单例Bean// Add boot specific singleton beansConfigurableListableBeanFactory beanFactory = context.getBeanFactory();beanFactory.registerSingleton("springApplicationArguments", applicationArguments);if (printedBanner != null) {beanFactory.registerSingleton("springBootBanner", printedBanner);}// spring容器设置AllowCircularReferences和allowBeanDefinitionOverridingif (beanFactory instanceof AbstractAutowireCapableBeanFactory) {((AbstractAutowireCapableBeanFactory) beanFactory).setAllowCircularReferences(this.allowCircularReferences);if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}}if (this.lazyInitialization) {context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}// Load the sources// 拿到启动配置(run方法传递进来的)Set<Object> sources = getAllSources();Assert.notEmpty(sources, "Sources must not be empty");// 将启动配置类解析为BeanDefinition注册到spring容器load(context, sources.toArray(new Object[0]));// 发布ApplicationPreparedEvent事件,表示已经启动好spring容器listeners.contextLoaded(context);}结束语