SpringBoot源码启动流程(待完善)

发布时间:2024年01月16日

SpringBoot源码启动流程

1. 构造SpringApplication对象

1.1 推测web应用类型

判断关键类是否存在来区分类型

  • REACTIVE
  • NONE
  • SERVLET
	static WebApplicationType deduceFromClasspath() {
		if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
				&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
			return WebApplicationType.REACTIVE;
		}
		for (String className : SERVLET_INDICATOR_CLASSES) {
			if (!ClassUtils.isPresent(className, null)) {
				return WebApplicationType.NONE;
			}
		}
		return WebApplicationType.SERVLET;
	}

2. 设置Initializers和Listeners扩展点

3. 推测Main方法所在类

	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();
        // 设置Initializer和Listener扩展点
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		// 推测main方法所在类
        this.mainApplicationClass = deduceMainApplicationClass();
	}

2.?run(String... args)方法

SpringApplicationRunListener.starting

SpringBoot提供了一个EventPublishingRunListener,它实现了SpringApplicationRunListener接口,默认情况下会利用EventPublishingRunListener发布一个ApplicationContextInitializedEvent事件,程序员可通过定义ApplicationListener来消费这个事件

		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();

创建Environment

解析配置文件, 环境变量, 启动命令参数

?

SpringApplicationRunListeners.environmentPrepared

用EventPublishingRunListener发布一个ApplicationEnvironmentPreparedEvent事件,默认情况会有一个EnvironmentPostProcessorApplicationListener来消费这个事件,而这个ApplicationListener接收到这个事件之后,就会解析application.properties、application.yml文件,并添加到Environment对象中去。

打印Banner

创建Spring容器

	protected ConfigurableApplicationContext createApplicationContext() {
		Class<?> contextClass = this.applicationContextClass;
		if (contextClass == null) {
			try {
				switch (this.webApplicationType) {
				case SERVLET:
					contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
					break;
				case REACTIVE:
					contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
					break;
				default:
					contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
				}
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass",
						ex);
			}
		}
		return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
	}

配置解析流程

SpringBoot配置优先级

官网描述:Core Features

?

  1. Default properties (specified by setting?SpringApplication.setDefaultProperties).

  2. @PropertySource?annotations on your?@Configuration?classes. Please note that such property sources are not added to the?Environment?until the application context is being refreshed. This is too late to configure certain properties such as?logging.*?and?spring.main.*?which are read before refresh begins.

  3. Config data (such as?application.properties?files).

  4. A?RandomValuePropertySource?that has properties only in?random.*.

  5. OS environment variables.

  6. Java System properties (System.getProperties()).

  7. JNDI attributes from?java:comp/env.

  8. ServletContext?init parameters.

  9. ServletConfig?init parameters.

  10. Properties from?SPRING_APPLICATION_JSON?(inline JSON embedded in an environment variable or system property).

  11. Command line arguments.

  12. properties?attribute on your tests. Available on?@SpringBootTest?and the?test annotations for testing a particular slice of your application.

  13. @DynamicPropertySource?annotations in your tests.

  14. @TestPropertySource?annotations on your tests.

  15. Devtools global settings properties?in the?$HOME/.config/spring-boot?directory when devtools is active.

Config data files are considered in the following order:

  1. Application properties?packaged inside your jar (application.properties?and YAML variants).

  2. Profile-specific application properties?packaged inside your jar (application-{profile}.properties?and YAML variants).

  3. Application properties?outside of your packaged jar (application.properties?and YAML variants).

  4. Profile-specific application properties?outside of your packaged jar (application-{profile}.properties?and YAML variants).

文章来源:https://blog.csdn.net/weixin_64027360/article/details/135613210
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。