SpringBoot(十一)——————SpringBoot启动配置原理

  • SpringBoot启动原理

重要的事件回调机制
           配置在META-INF/spring.factories
          ApplicationContextInitializer
          SpringApplicationRunListener
          只需要放在ioc容器中
          ApplicationRunner
          CommandLineRunner

1)、启动入口

@SpringBootApplication
public class SpringbootIntegrateApplication {

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

}

2)、创建SpringApplication对象

	public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
		return new SpringApplication(primarySources).run(args);
	}
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();
	}
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
	this.resourceLoader = resourceLoader;
	Assert.notNull(primarySources, "PrimarySources must not be null");
	//保存主配置类
	this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
	//判断当前是否web应用
	this.webApplicationType = WebApplicationType.deduceFromClasspath();
	//从类路径下找到META‐INF/spring.factories配置的所有ApplicationContextInitializer;并保存
	setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
	//从类路径下找到ETA‐INF/spring.factories配置的所有ApplicationListener;并保存
	setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
	//从多个配置类中找到有main方法的主配置类
	this.mainApplicationClass = deduceMainApplicationClass();
}
  • setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); 

  •  setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

3)、运行run方法

	public ConfigurableApplicationContext run(String... args) {
		//创建监听
		StopWatch stopWatch = new StopWatch();
		//监听启动
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
		//从类路径下META‐INF/spring.factories获取SpringApplicationRunListeners;
		SpringApplicationRunListeners listeners = getRunListeners(args);
		//回调所有的starting
		listeners.starting();
		try {
			//封装命令行参数
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			//准备环境
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			configureIgnoreBeanInfo(environment);
			//打印Spring图标
			Banner printedBanner = printBanner(environment);
			//创建IOC容器
			context = createApplicationContext();
			//出现异常后作异常分写报告
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
			//准备上下文
			prepareContext(context, environment, listeners, applicationArguments, printedBanner);
			//刷新IOC容器,IOC容器初始化。扫描,创建,加载所有组件。如果是web应用还会创建嵌入式的Tomcat
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
			}
			//回调started方法
			listeners.started(context);
			//从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调	
			//ApplicationRunner先回调,CommandLineRunner再回调
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}

		try {
			//回调running方法
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		//SpringBoot应用启动完成返回IOC容器
		return context;
	}
  •  ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
		ApplicationArguments applicationArguments) {
	// Create and configure the environment
	//获取或者创建环境
	ConfigurableEnvironment environment = getOrCreateEnvironment();
	configureEnvironment(environment, applicationArguments.getSourceArgs());
	ConfigurationPropertySources.attach(environment);
	//回调environmentPrepared方法,环境准备完成
	listeners.environmentPrepared(environment);
	//将环境绑定到SpringApplication
	bindToSpringApplication(environment);
	//不是web环境转换成web环境
	if (!this.isCustomEnvironment) {
		environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
				deduceEnvironmentClass());
	}
	ConfigurationPropertySources.attach(environment);
	return environment;
}
  • prepareContext(context, environment, listeners, applicationArguments, printedBanner);
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
			SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
		//将environment保存到IOC容器中
		context.setEnvironment(environment);
		postProcessApplicationContext(context);
		//回调前面获取的ApplicationContextInitializer的initialize方法
		applyInitializers(context);
		//回调SpringApplicationRunListeners的contextPrepared方法
		listeners.contextPrepared(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]));
		//回调SpringApplicationRunListeners的contextLoaded方法
		listeners.contextLoaded(context);
	}
发布了101 篇原创文章 · 获赞 10 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/WMY1230/article/details/104321293