[Ежедневный свежий гриб] Как движется SpringBoot?

Микросервисы

Запись программы

SpringApplication.run(BeautyApplication.class, args);

Выполните этот метод, чтобы загрузить всю среду SpringBoot.

1. С чего начать?

SpringApplication.java

	/**
	 * Run the Spring application, creating and refreshing a new
	 * {@link ApplicationContext}.
	 * @param args the application arguments (usually passed from a Java main method)
	 * @return a running {@link ApplicationContext}
	 */
	public ConfigurableApplicationContext run(String... args) {
		//...
  }

перечислитьSpringApplication.javaМетод run в , целью которого является загрузкаSpring Application, при возвращенииApplicationContext.

2. Что выполняется?

2.1 Сроки

записать весьSpring ApplicationВремя загрузки!

StopWatch stopWatch = new StopWatch();
stopWatch.start();
// ...
stopWatch.stop();
if (this.logStartupInfo) {
	new StartupInfoLogger(this.mainApplicationClass)
			.logStarted(getApplicationLog(), stopWatch);
}

2.2 Заявление

// 声明 ApplicationContext
ConfigurableApplicationContext context = null;
// 声明 一个异常报告集合
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();

2.3 Укажите режим работы программы

уточнитьjava.awt.headless, по умолчаниюtrueОбычно программа начинает активировать безголовый режим, сообщая программе, что теперь вы хотите работать в безголовом режиме, не полагайтесь на аппаратное обеспечение, вы должны полагаться на вычислительную мощность системы для имитации этих характеристики.

private void configureHeadlessProperty() {
	System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, System.getProperty(
			SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless)));
}

2.4 Настройка для мониторинга и публикации событий запуска приложений

SpringApplicationRunListenerОтвечает за загрузкуApplicationListenerсобытие.

SpringApplicationRunListeners listeners = getRunListeners(args);
// 开始
listeners.starting();
// 处理所有 property sources 配置和 profiles 配置,准备环境,分为标准 Servlet 环境和标准环境
ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);
// 准备应用上下文
prepareContext(context, environment, listeners, applicationArguments,printedBanner);
// 完成
listeners.started(context);
// 异常
handleRunFailure(context, ex, exceptionReporters, listeners);
// 执行
listeners.running(context);

getRunListenersв соответствии сtype = SpringApplicationRunListener.classполучить всеListenerи отсортированы по приоритету. соответствуетMETA-INF/spring.factoriesв файлеorg.springframework.boot.SpringApplicationRunListener=org.springframework.boot.context.event.EventPublishingRunListener

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
			Class<?>[] parameterTypes, Object... args) {
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		// Use names and ensure unique to protect against duplicates
		Set<String> names = new LinkedHashSet<>(
				SpringFactoriesLoader.loadFactoryNames(type, classLoader));
		List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
				classLoader, args, names);
		AnnotationAwareOrderComparator.sort(instances);
		return instances;
	}

существуетApplicationListener, может быть нацелен на любой этап插入处理代码.

public interface SpringApplicationRunListener {

	/**
	 * Called immediately when the run method has first started. Can be used for very
	 * early initialization.
	 */
	void starting();

	/**
	 * Called once the environment has been prepared, but before the
	 * {@link ApplicationContext} has been created.
	 * @param environment the environment
	 */
	void environmentPrepared(ConfigurableEnvironment environment);

	/**
	 * Called once the {@link ApplicationContext} has been created and prepared, but
	 * before sources have been loaded.
	 * @param context the application context
	 */
	void contextPrepared(ConfigurableApplicationContext context);

	/**
	 * Called once the application context has been loaded but before it has been
	 * refreshed.
	 * @param context the application context
	 */
	void contextLoaded(ConfigurableApplicationContext context);

	/**
	 * The context has been refreshed and the application has started but
	 * {@link CommandLineRunner CommandLineRunners} and {@link ApplicationRunner
	 * ApplicationRunners} have not been called.
	 * @param context the application context.
	 * @since 2.0.0
	 */
	void started(ConfigurableApplicationContext context);

	/**
	 * Called immediately before the run method finishes, when the application context has
	 * been refreshed and all {@link CommandLineRunner CommandLineRunners} and
	 * {@link ApplicationRunner ApplicationRunners} have been called.
	 * @param context the application context.
	 * @since 2.0.0
	 */
	void running(ConfigurableApplicationContext context);

	/**
	 * Called when a failure occurs when running the application.
	 * @param context the application context or {@code null} if a failure occurred before
	 * the context was created
	 * @param exception the failure
	 * @since 2.0.0
	 */
	void failed(ConfigurableApplicationContext context, Throwable exception);

}

3. Что делать на каждом этапе

3.1 listeners.starting();

Выполняется до загрузки приложения Spring, все ресурсы и среды не загружаются.

3.2 prepareEnvironment(listeners, applicationArguments);

СоздайтеConfigurableEnvironment; Привязать настроенную среду кSpring Applicationсередина;

	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.webApplicationType == WebApplicationType.NONE) {
			environment = new EnvironmentConverter(getClassLoader())
					.convertToStandardEnvironmentIfNecessary(environment);
		}
		ConfigurationPropertySources.attach(environment);
		return environment;
	}

3.3 prepareContext

Конфигурация игнорирует Bean;

	private void configureIgnoreBeanInfo(ConfigurableEnvironment environment) {
		if (System.getProperty(
				CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME) == null) {
			Boolean ignore = environment.getProperty("spring.beaninfo.ignore",
					Boolean.class, Boolean.TRUE);
			System.setProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME,
					ignore.toString());
		}
	}

журнал печати - загруженные ресурсы

Banner printedBanner = printBanner(environment);

по разнымWebApplicationTypeСоздать контекст

context = createApplicationContext();

3.4 refreshContext

Поддержка пользовательского обновления

	/**
	 * Register a shutdown hook with the JVM runtime, closing this context
	 * on JVM shutdown unless it has already been closed at that time.
	 * <p>This method can be called multiple times. Only one shutdown hook
	 * (at max) will be registered for each context instance.
	 * @see java.lang.Runtime#addShutdownHook
	 * @see #close()
	 */
	void registerShutdownHook();

3.5 afterRefresh

Обновленный метод реализации еще не реализован

	/**
	 * Called after the context has been refreshed.
	 * @param context the application context
	 * @param args the application arguments
	 */
	protected void afterRefresh(ConfigurableApplicationContext context,
			ApplicationArguments args) {
	}

3.6 listeners.started(context);

Уже,Spring ApplicationОкружение и ресурсы загружены; Опубликовать событие завершения запуска контекста приложения; Execute all Runners — выполняются как ApplicationRunner, так и CommandLineRunner.

// 启动
callRunners(context, applicationArguments);

3.7 listeners.running(context);

Запускает метод текущего события всех прослушивателей SpringApplicationRunListener.