Program entrance

SpringApplication.run(BeautyApplication.class, args);
Copy the code

Execute this method to load the entire SpringBoot environment.

1. Where to start?

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) {
		/ /...
  }
Copy the code

Call the run method in SpringApplication.java to load the SpringApplication and return the ApplicationContext.

2. What was implemented?

2.1 the timing

Record the load time of the entire Spring Application!

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

2.2 the statement

/ / declare ApplicationContext
ConfigurableApplicationContext context = null;
Declare a collection of exception reports
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
Copy the code

2.3 Specify the program running mode

Specifying java.awt.headless, which defaults to true, is usually done when the application starts to activate headless mode, telling the application that now that you want to work in Headless mode, you need to rely on the computing power of the system to simulate these features.

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

2.4 Configuring Listening and Publishing application startup events

SpringApplicationRunListener is responsible for loading ApplicationListener events.

SpringApplicationRunListeners listeners = getRunListeners(args);
/ /
listeners.starting();
// Handle all property Sources configuration and Profiles configuration, prepare environment, divided into standard Servlet environment and standard environment
ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);
// Prepare the application context
prepareContext(context, environment, listeners, applicationArguments,printedBanner);
/ / finish
listeners.started(context);
/ / exception
handleRunFailure(context, ex, exceptionReporters, listeners);
/ / execution
listeners.running(context);
Copy the code

According to type = in getRunListeners SpringApplicationRunListener. Class to get the all the Listener according to priority. The corresponding is in the meta-INF /spring.factories file org.springframework.boot.SpringApplicationRunListener=org.springframework.boot.context.event.EventPublishingRunListener

private <T> Collection<T> getSpringFactoriesInstances(Class
       
         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;
	}
Copy the code

In ApplicationListener, you can insert processing code for any of the phases.

public interface SpringApplicationRunListener {

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

	/**
	 * 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.
	 * @since2.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.
	 * @since2.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
	 * @since2.0.0 * /
	void failed(ConfigurableApplicationContext context, Throwable exception);

}
Copy the code

3. What is executed at each stage

3.1 listeners. Starting ();

Before the Spring Application is loaded, all resources and environments are not loaded.

3.2 prepareEnvironment (listeners, applicationArguments);

Create ConfigurableEnvironment; Bind the configured environment to 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;
	}
Copy the code

3.3 prepareContext

Configure ignored beans;

	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()); }}Copy the code

Print logs – Loaded resources

Banner printedBanner = printBanner(environment);
Copy the code

Create Context based on different WebApplicationTypes

context = createApplicationContext();
Copy the code

3.4 refreshContext

Support customization refresh

	/**
	 * 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(a);
Copy the code

3.5 afterRefresh

The updated implementation method is not implemented yet

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

3.6 listeners. Started (context);

At this point, the Spring Application environment and resources are loaded; Publish the application context startup completion event Run all Runner runners – Run all ApplicationRunner and CommandLineRunner runners

/ / start
callRunners(context, applicationArguments);
Copy the code

3.7 listeners. Running (context);

Trigger all SpringApplicationRunListener listener running event method