乐趣区

关于springboot:81-SpringBoot启动流程把spring应用跑起来

创立 IOC 容器 createApplicationContext()

protected ConfigurableApplicationContext createApplicationContext() {return this.applicationContextFactory.create(this.webApplicationType);
    }
============= 依据以后的利用类型(Servlet)创立容器
// 以后会创立 AnnotationConfigServletWebServerApplicationContext
ApplicationContextFactory DEFAULT = (webApplicationType) -> {
        try {switch (webApplicationType) {
            case SERVLET:
                return new AnnotationConfigServletWebServerApplicationContext();
            case REACTIVE:
                return new AnnotationConfigReactiveWebServerApplicationContext();
            default:
                return new AnnotationConfigApplicationContext();}
        }
        catch (Exception ex) {
            throw new IllegalStateException("Unable create a default ApplicationContext instance,"
                    + "you may need a custom ApplicationContextFactory", ex);
        }
    };

筹备 ApplicationContext IOC 容器的根本信息 prepareContext()

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
            ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments, Banner printedBanner) {
        // 保留后面的根底环境
        context.setEnvironment(environment);
        //IOC 容器的后置解决流程。postProcessApplicationContext(context);
        // 利用初始化器:applyInitializers
        applyInitializers(context);
        // 遍历所有的 listener 调用 contextPrepared
        //ioc 容器的环境准备就绪了 (contextPrepared 办法的源码在上面)
        listeners.contextPrepared(context);
        // 疏导上下文的环境敞开了
        bootstrapContext.close(context);
        if (this.logStartupInfo) {logStartupInfo(context.getParent() == null);
            logStartupProfileInfo(context);
        }
        // Add boot specific singleton beans
        // 拿到 bean 工厂
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        // 注册单实例
        beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
        // 打印 banner
        if (printedBanner != null) {beanFactory.registerSingleton("springBootBanner", printedBanner);
        }
        if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory) beanFactory)
                    .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }
        if (this.lazyInitialization) {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]));
        //listeners: 监听器
        listeners.contextLoaded(context);
    }

================== postProcessApplicationContext(context);
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {if (this.beanNameGenerator != null) {
// 注册组件
            context.getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
                    this.beanNameGenerator);
        }

        if (this.resourceLoader != null) {
        // 读取配置文件的资源
            if (context instanceof GenericApplicationContext) {((GenericApplicationContext) context).setResourceLoader(this.resourceLoader);
            }

            if (context instanceof DefaultResourceLoader) {
        // 资源加载器
                ((DefaultResourceLoader) context).setClassLoader(this.resourceLoader.getClassLoader());
            }
        }

        // 筹备类型转换器
        if (this.addConversionService) {context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance());
        }
    }

===================applyInitializers(context)
protected void applyInitializers(ConfigurableApplicationContext context) {
// 遍历所有的 ApplicationContextInitializer。调用 initialize。来对 ioc 容器进行初始化扩大性能
        for (ApplicationContextInitializer initializer : getInitializers()) { // 之前从 spring.factories 找进去的七个 Initializer
            Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
                    ApplicationContextInitializer.class);
            Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
            initializer.initialize(context);
        }
    }

@Override
    public void initialize(ConfigurableApplicationContext context) {ConfigurableEnvironment environment = context.getEnvironment();
        List<Class<?>> initializerClasses = getInitializerClasses(environment);
    // 如果 initializerClasses 不为空,就把他们实例化。if (!initializerClasses.isEmpty()) {applyInitializerClasses(context, initializerClasses);
        }
    }

===========contextPrepared()void contextPrepared(ConfigurableApplicationContext context) {doWithListeners("spring.boot.application.context-prepared", (listener) -> listener.contextPrepared(context));
}

private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction) {doWithListeners(stepName, listenerAction, null);
}

private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction,
            Consumer<StartupStep> stepAction) {StartupStep step = this.applicationStartup.start(stepName);
        // 拿到所有的 listeners
        // 实际上是 EventPublishRunListenr:告诉所有的监听器 contextPrepared 容器的上下文环境曾经筹备好了
        this.listeners.forEach(listenerAction);
        if (stepAction != null) {stepAction.accept(step);
        }
        step.end();}

================contextLoaded()
void contextLoaded(ConfigurableApplicationContext context) {doWithListeners("spring.boot.application.context-loaded", (listener) -> listener.contextLoaded(context));
}

private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction) {doWithListeners(stepName, listenerAction, null);
}

private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction,
            Consumer<StartupStep> stepAction) {StartupStep step = this.applicationStartup.start(stepName);
    // 所有的监听器去调用 contextLoaded(context)
    // 告诉所有的监听器 contextLoaded;容器的上下文环境曾经加载好了
        this.listeners.forEach(listenerAction);
        if (stepAction != null) {stepAction.accept(step);
        }
        step.end();}

(listener) -> listener.contextLoaded(context)
退出移动版