springboot启动流程学习

SpringApplication初始化

// An highlighted block
package com.nwd;

import cn.hutool.extra.spring.EnableSpringUtil;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableSpringUtil
public class AopTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(AopTestApplication.class, args);
    }

}
/**
  * 先创建SpringApplication对象,再执行run()方法
  */
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
		return new SpringApplication(primarySources).run(args);
	}

1.确定应用程序类型
2.获取bootstrappers:初始启动引导器
3.获取ApplicationContextInitializer初始化器
4.获取ApplicationListener 应用监听器
5.设置程序运行的主类

// An highlighted block
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();
		this.bootstrappers = new ArrayList<>(getSpringFactoriesInstances(Bootstrapper.class));
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}

执行run()方法

// An highlighted block
// org.springframework.boot.SpringApplication#run(java.lang.String...)
public ConfigurableApplicationContext run(String... args) {
   // 应用停止监听器
   StopWatch stopWatch = new StopWatch();
   stopWatch.start(); // 记录应用的启动时间
 
   // 创建引导上下文(Context环境)createBootstrapContext()
   DefaultBootstrapContext bootstrapContext = createBootstrapContext();
   ConfigurableApplicationContext context = null;
   // 设置headless属性方法(java.awt.headless),让当前应用进入headless模式(自力更生模式,详情自行百度)
   configureHeadlessProperty();
   //获取所有 RunListener(运行监听器)【为了方便所有Listener进行事件感知】
   SpringApplicationRunListeners listeners = getRunListeners(args);
   // 遍历 SpringApplicationRunListener 调用 starting 方法,相当于通知所有对系统正在启动过程感兴趣的人,项目正在 starting。
   listeners.starting(bootstrapContext, this.mainApplicationClass);
   try {
      // 保存命令行参数;ApplicationArguments
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      // 准备运行时环境
      ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
      configureIgnoreBeanInfo(environment);
      // 打印banner
      Banner printedBanner = printBanner(environment);
      // 创建IOC容器
      // 根据项目类型(Servlet)创建容器,当前会创建 AnnotationConfigServletWebServerApplicationContext
      context = createApplicationContext();
      context.setApplicationStartup(this.applicationStartup);
      // 准备ApplicationContext IOC容器的基本信息
      prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
      // 刷新IOC容器,调用IOC容器的经典初始化过程,创建容器中的所有组件
      refreshContext(context);
      // 容器刷新完成后工作,方法是空的
      afterRefresh(context, applicationArguments);
      // 监控花费的时间
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
      }
      // 所有监听器 调用 listeners.started(context); 通知所有的监听器 started
      listeners.started(context);
      // 调用所有runners
      callRunners(context, applicationArguments);
   }
   // 如果有异常,调用Listener 的 failed方法
   catch (Throwable ex) {
      handleRunFailure(context, ex, listeners);
      throw new IllegalStateException(ex);
   }
 
   try {
      // 调用所有监听器的 running 方法 listeners.running(context); 通知所有的监听器 running
      listeners.running(context);
   }
   // running如果有问题。继续通知 failed 。调用所有 Listener 的 failed;通知所有的监听器 failed
   catch (Throwable ex) {
      handleRunFailure(context, ex, null);
      throw new IllegalStateException(ex);
   }
   return context;
}

(1)创建引导上下文(Context环境)

// An highlighted block
private DefaultBootstrapContext createBootstrapContext() {
   DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext(); // 创建默认的引导上下文
   // 获取到所有之前的 bootstrappers 挨个执行 intitialize() 来完成对引导启动器上下文环境设置
   this.bootstrappers.forEach((initializer) -> initializer.intitialize(bootstrapContext));
   return bootstrapContext;
}

(2)bootstrapper其实是个接口

// An highlighted block
public interface Bootstrapper {
 
   /**
    * Initialize the given {@link BootstrapRegistry} with any required registrations.
    * @param registry the registry to initialize
    */
   void intitialize(BootstrapRegistry registry);
}

(3)获取所有 RunListener(运行监听器)

// An highlighted block
private SpringApplicationRunListeners getRunListeners(String[] args) {
   Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
   return new SpringApplicationRunListeners(logger,
         getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args),
         this.applicationStartup);
}

(4)准备运行时环境

// An highlighted block
// org.springframework.boot.SpringApplication#prepareEnvironment
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
      DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
   // Create and configure the environment
   // 返回或者创建基础环境信息对象。StandardServletEnvironment
   ConfigurableEnvironment environment = getOrCreateEnvironment();
   // 配置环境信息,通过命令行参数或者配置文件获取配置属性值
   configureEnvironment(environment, applicationArguments.getSourceArgs());
   // 绑定环境信息
   ConfigurationPropertySources.attach(environment);
   // 所有监听器遍历调用 listener.environmentPrepared();通知所有的监听器当前环境准备完成
   listeners.environmentPrepared(bootstrapContext, environment);
   DefaultPropertiesPropertySource.moveToEnd(environment);
   // 激活额外的环境
   configureAdditionalProfiles(environment);
   // 绑定一些值
   bindToSpringApplication(environment);
   if (!this.isCustomEnvironment) {
      environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
            deduceEnvironmentClass());
   }
   ConfigurationPropertySources.attach(environment);
   return environment;
}

(5)创建IOC容器

// An highlighted block
// org.springframework.boot.SpringApplication#createApplicationContext
protected ConfigurableApplicationContext createApplicationContext() {
   // 根据项目类型(Servlet)创建容器,当前会创建 AnnotationConfigServletWebServerApplicationContext
   return this.applicationContextFactory.create(this.webApplicationType);
}

(6)准备ApplicationContext IOC容器的基本信息

// An highlighted block
// org.springframework.boot.SpringApplication#prepareContext
private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
      ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
      ApplicationArguments applicationArguments, Banner printedBanner) {
   // 保存基础环境信息
   context.setEnvironment(environment);
   // IOC容器的后置处理流程(注册一些组件、读取配置文件资源、注册资源加载器、准备类型转换器等等)
   postProcessApplicationContext(context);
   // 应用初始化器:applyInitializers
   // 遍历所有的 ApplicationContextInitializer 。调用 initialize方法。来对ioc容器进行初始化扩展功能
   applyInitializers(context);
   // 遍历所有的 listener 调用 contextPrepared方法。
   listeners.contextPrepared(context);
   bootstrapContext.close(context);
   if (this.logStartupInfo) {
      logStartupInfo(context.getParent() == null);
      logStartupProfileInfo(context);
   }
   // Add boot specific singleton beans
   ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
   beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
   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]));
   // 所有的监听器 调用 contextLoaded。通知所有的监听器 contextLoaded
   listeners.contextLoaded(context);
}

(7)IOC容器的经典初始化过程
spring容器创建及加载

  1. 创建BeanFactory对象 ConfigurableListableBeanFactory beanFactory =
    obtainFreshBeanFactory();
  2. 设置beanFactory准备完成进行的后置处理工作 postProcessBeanFactory(beanFactory);
  3. 调用上下文中注册为bean的工厂处理器 invokeBeanFactoryPostProcessors(beanFactory);
    执行BeanFactoryPostProcessor
    BeanFactoryPostProcessor:BeanFactory的后置处理器。在BeanFactory标准初始化之后执行的。
    两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor

执行BeanFactoryPostProcessor

先执行BeanDefinitionRegistryPostProcessor

1)获取所有的BeanDefinitionRegistryPostProcessor

2)先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor,执行postProcessor.postProcessBeanDefinitionRegistry(registry);

3)再执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor,执行postProcessor.postProcessBeanDefinitionRegistry(registry);

4)最后执行没有实现任何优先级或者顺序接口的BeanDefinitionRegistryPostProcessor,执行postProcessor.postProcessBeanDefinitionRegistry(registry);

再执行BeanFactoryPostProcessor的方法

1)获取所有的BeanFactoryPostProcessor

2)先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor,执行postProcessor.postProcessBeanFactory(beanFactory);

3)再执行实现了Ordered顺序接口的BeanFactoryPostProcessor,执行postProcessor.postProcessBeanFactory(beanFactory);

4)最后执行没有实现任何优先级或者顺序接口的BeanFactoryPostProcessor,执行postProcessor.postProcessBeanFactory(beanFactory);
  1. 注册BeanPostProcessors(bean的后置处理器)
    registerBeanPostProcessors(beanFactory);
    【拦截bean的创建过程】

几个接口(不同接口类型的BeanPostProcessor,在Bean创建前后的执行时机是不一样的):

BeanPostProcessor 、

DestructionAwareBeanPostProcessor、

InstantationAwareBeanPostProcessor、

SmartInstantationAwareBeanPostProcessor、

MergedBeanDefinitionPostProcessor【放在internalPostProcessors里】。

(1)获取所有的BeanPostProcessor,后置处理器都默认可以通过PriorityOrdered、Ordered接口来指定优先级

(2)先注册PriorityOrdered优先级接口的BeanPostProcessor。

把每一个BeanPostProcessor添加到beanFactory中。beanFactory.addBeanPostProcessor(postProcessor);

(3)再注册实现Ordered接口的。

(4)最后注册没有实现任何优先级接口的。

(5)最终注册MergedBeanDefinitionPostProcessor。

(6)注册一个ApplicationListenerDetector,在Bean创建完之后检查是否是ApplicationListenerDetector,如果是,applicationContext.addApplicationListener((ApplicationListener<?>) bean);

  1. registerListeners();给容器中将项目里面的ApplicationListener注册进来

(1)从容器中拿到所有的ApplicationListener组件。

(2)将每个监听器添加到事件派发器中。

(3)派发之前步骤产生的事件。

  1. finishBeanFactoryInitialization(beanFactory);初始化所有剩下的单实例bean

链接: https://blog.csdn.net/A_art_xiang/article/details/121954905
链接: https://blog.csdn.net/A_art_xiang/article/details/122437676

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值