springBoot启动全流程如下所示:
框架初始化,完成相关配置:
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); this.webApplicationType = WebApplicationType.deduceFromClasspath(); setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass(); }
执行run方法:
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>(); configureHeadlessProperty(); SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(); try { ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); configureIgnoreBeanInfo(environment); Banner printedBanner = printBanner(environment); context = createApplicationContext(); exceptionReporters = getSpringFactoriesInstances( SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context); prepareContext(context, environment, listeners, applicationArguments, printedBanner); refreshContext(context); afterRefresh(context, applicationArguments); stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } listeners.started(context); callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } try { listeners.running(context); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, null); throw new IllegalStateException(ex); } return context; }
springBoot环境准备:
1 Devtools全局配置 2 测试环境@TestPropertySource注解 3 测试环境properties属性 4 命令行参数 5 SPRING_APPLICATION_JSON属性 6 ServletConfig初始化参数 7 ServletContext初始化参数 8JNDI属性 9 JAVA系统属性 10 操作系统环境变量 11 RandomValuePropertySource随机值属性 12 jar包外的application-{profile}.properties 13 jar包内的application-{profile}.properties 14 jar包外的application.properties 15 14 jar包内的application.properties 16 @PropertySource绑定配置 17 默认属性
private ConfigurableEnvironment prepareEnvironment( SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) { // Create and configure the environment ConfigurableEnvironment environment = getOrCreateEnvironment(); configureEnvironment(environment, applicationArguments.getSourceArgs()); listeners.environmentPrepared(environment); bindToSpringApplication(environment); if (!this.isCustomEnvironment) { environment = new EnvironmentConverter(getClassLoader()) .convertEnvironmentIfNecessary(environment, deduceEnvironmentClass()); } ConfigurationPropertySources.attach(environment); return environment; }
环境准备流程图解析:
准备上下文:
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { context.setEnvironment(environment); postProcessApplicationContext(context); //遍历调用Initializer的Initilize方法 applyInitializers(context); //发送ApplicationContextInitializedEvent事件 listeners.contextPrepared(context); if (this.logStartupInfo) { logStartupInfo(context.getParent() == null); logStartupProfileInfo(context); } // Add boot specific singleton beans ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //注册springApplicationArguments beanFactory.registerSingleton("springApplicationArguments", applicationArguments); if (printedBanner != null) { //springBootBanner beanFactory.registerSingleton("springBootBanner", printedBanner); } if (beanFactory instanceof DefaultListableBeanFactory) { ((DefaultListableBeanFactory) beanFactory) .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } //加载sources Set<Object> sources = getAllSources(); Assert.notEmpty(sources, "Sources must not be empty"); load(context, sources.toArray(new Object[0])); //发送ApplicationPreparedEvent事件 listeners.contextLoaded(context); }
刷新上下文
obtainFreshBeanFactory方法内部通过调用loadBeanDefinitions方法完成了bean定义的加载。
PrepareBeanFactory内部配置工厂的标准上下文特征,例如上下文的ClassLoader和后处理器postProcessors.
postProcessBeanFactory方法允许在bean没有实例化前允许修改应用上下文的内部beanFactory, 允许注册特殊的beanPostProcessors
invokeBeanFactoryPostProcessors方法实例化并调用所有注册的BeanFactoryPostProcessor bean
finishBeanFactoryInitialization方法实例化所有非惰性加载单例bean, 通过defaultListableBeanFactory的preInstantiateSingletons实例化单例bean,具体创建由abstractBeanFactory的getBean方法完成,从这里开始就和spring实例化bean有些类似了。
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(); } //所属类:ApplicationContext public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //准备刷新此上下文。 prepareRefresh(); //告诉子类刷新内部bean工厂 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //准备bean工厂以便在此上下文中使用。 prepareBeanFactory(beanFactory); try { //允许在上下文子类中对bean工厂进行后处理。 //在标准初始化之后修改应用程序上下文的内部bean工厂。 //所有的bean定义都将被加载,但还没有任何bean被实例化。这允许在某些ApplicationContext实现中注册特殊的BeanPostProcessors postProcessBeanFactory(beanFactory); //调用在上下文中注册为bean的工厂处理器(beanFactoryPostProcessor) invokeBeanFactoryPostProcessors(beanFactory); //注册拦截bean创建的bean处理器。 registerBeanPostProcessors(beanFactory); //初始化此上下文的消息源。 initMessageSource(); //初始化此上下文的事件多播。 initApplicationEventMulticaster(); //初始化特定上下文子类中的其他特殊bean。 onRefresh(); //检查侦听器bean并注册它们。 registerListeners(); //实例化所有剩余的(非惰性init)singleton。 finishBeanFactoryInitialization(beanFactory); //最后一步:发布相应的事件。 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } //销毁已创建的singleton以避免挂起资源。 destroyBeans(); cancelRefresh(ex); throw ex; } finally { //重置Spring核心中的常见内省缓存,因为我们可能再也不需要单例bean的元数据了。。。 resetCommonCaches(); } } }标签:SpringBoot,beanFactory,启动,listeners,environment,bean,context,上下文 From: https://www.cnblogs.com/mtjb1dd/p/17903082.html