SpringBoot 2.0.x startup process

Posted by alexz on Fri, 12 Jun 2020 05:35:04 +0200

The entry class of SpringBoot

@SpringBootApplication
public class SpringbootApplication {

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

}

As can be seen from the entry class, in the Main method, run is executed; let's go to the run method to have a look

run method code

Obviously, this is an overloaded method, which is just like the static help method marked in red box; then go down

Here comes the point: here is a two-step analysis. Let's talk about what we have done in the next two steps.

Step 1:

As you can see from the code, there are only seven lines of valid code. In the first step, you do seven things:

1. Resource loader initialized to null

this.resourceLoader = resourceLoader;

2. Assert that the primary resource loader cannot be null

Assert.notNull(primarySources, "PrimarySources must not be null");

3. Put the primary resource loader into the resource loader and de duplicate (Set has its own de duplication function)

this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));

4. Infer web application type

this.webApplicationType = deduceWebApplicationType();

5. Application context factory instance initialization

setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));

6. Application listener factory instance initialization

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

7. Infer the main class of main method in application entry

this.mainApplicationClass = deduceMainApplicationClass();

After analyzing the big box of the first step, first don't worry about looking at the specific logic of each step. Next, look at the run method of the second step. The run method has a lot of code, which doesn't matter a little bit

    /**
	 * 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) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
			configureIgnoreBeanInfo(environment);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			exceptionReporters = getSpringFactoriesInstances(
					SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass)
						.logStarted(getApplicationLog(), stopWatch);
			}
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}

		try {
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}

Point by point analysis:

1. Create and start listening class;

2. Combination of initialization application context and exception report

3. Set system properties“ java.awt.headless ”The default value is true

4. Get the application running listener and start the listener

5. Initialize default application parameter class

6. Prepare environment according to running listener and application parameter class

7. Create Banner print class

8. Create application context

9. Get exception reporter based on context

10. Prepare application context according to environment, listener, application parameters and banner

11. Refresh application context

12. Refresh application context follow up

13. Stop timing listening class

14. Output log to record execution main class name and time information

15. Publish application context start completion event

16. Execute all runner runners

17. Publish application context ready event

18. Return context

So far, the two-step big box analysis is finished! Specific internal implementation, free to continue to write it!

reference resources:

https://mp.weixin.qq.com/s/RPU5gwvuWMyzUV8wFZziIw

https://www.jianshu.com/p/714f7b054041

Topics: Java SpringBoot Spring