Spring Boot-depth understanding of: parsing the boot process (start from the console) (2/3)

Copyright notice: reproduced please indicate the source and marked "AI algorithms Wuhan study" https://blog.csdn.net/qq_36931982/article/details/84104268

The second phase is about to start calling Spring Boot run () method, which returns a ConfigurableApplicationContext objects, ConfigurableApplicationContext which inherits the interface ApplicationContext, Lifecycel and Closeable, context is a process running in the Spring, increase on the basis of the ApplicationContext a series of configuration application context function. And application context configuration control method applied to context lifetime is encapsulated in this interface, so the client application directly.

/**
 * SPI interface to be implemented by most if not all application contexts.
 * Provides facilities to configure an application context in addition
 * to the application context client methods in the
 * {@link org.springframework.context.ApplicationContext} interface.
 *
 * <p>Configuration and lifecycle methods are encapsulated here to avoid
 * making them obvious to ApplicationContext client code. The present
 * methods should only be used by startup and shutdown code.
 *
 * @author Juergen Hoeller
 * @author Chris Beams
 * @since 03.11.2003
 */
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {}
	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;
	}

The above is a detailed step run () method, wherein the first step is to start the timing tool StopWatch.start () where StopWatch is a simple stopwatch, but also initialize the two objects, ConfigrableApplicationContexxt and exceptionReporters. After a set of system parameters, since no image of the web project is provided java.awt.headless system property is true.

After, getRunListeners (), get SpringApplicationRunListeners. SpringApplicationRunListener can listen to some of the life-cycle events springboot application starts the process, and do some processing. SpringApplicationRunListeners contains more SpringApplicationRunListener.

/**
 * Listener for the {@link SpringApplication} {@code run} method.
 * {@link SpringApplicationRunListener}s are loaded via the {@link SpringFactoriesLoader}
 * and should declare a public constructor that accepts a {@link SpringApplication}
 * instance and a {@code String[]} of arguments. A new
 * {@link SpringApplicationRunListener} instance will be created for each run.
 *
 * @author Phillip Webb
 * @author Dave Syer
 * @author Andy Wilkinson
 */
public interface SpringApplicationRunListener {
     //刚执行run方法时
    void started();
     //环境建立好时候
    void environmentPrepared(ConfigurableEnvironment environment);
     //上下文建立好的时候
    void contextPrepared(ConfigurableApplicationContext context);
    //上下文载入配置时候
    void contextLoaded(ConfigurableApplicationContext context);
    //上下文刷新完成后,run方法执行完之前
    void finished(ConfigurableApplicationContext context, Throwable exception);
}

SpringApplicationRunListener implementation class EventPublishingRunListener, which has a function that broadcasts the event. Responsible for publishing SpringApplicationEvent event, it will use an internal ApplicationEventMulticaster to handle the event before the actual context is refreshed.

After, new DefaultApplicationArguments (args) will initialize a ApplicationArguments, since the object has been initialized, then certainly have been entered, filling parameters,

After, prepareEnvironment (listeners, applicationArguments), this time to configure parameters for the environment, Web application terms, environment variable is an instance of a StandardServletEnvironment, after obtaining instance, calls the method described above RunListeners environmentPrepared in (a ApplicationEnvironmentPreparedEvent release event, after the release of this event will be able to make the appropriate treatment to existing listeners in the process of initializing SpringApplication initialized in the part of the listener).

After that, the print banner

After, createApplicationContext () created context. org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext, while calls to initialize class BeanUtils

After, prepareContext (context, environment, listeners, applicationArguments, printedBanner) a context process, wherein forget the context (ApplicationContext) provided their environment setEnvironment (environment), which contains two starting attention listening operation, corresponding to the front of the listener .

private void prepareContext(ConfigurableApplicationContext context,
        ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
        ApplicationArguments applicationArguments, Banner printedBanner) {
    // 将环境和上下文关联起来
    context.setEnvironment(environment);
    // 为上下文配置Bean生成器以及资源加载器(如果它们非空)
    postProcessApplicationContext(context);
    // 调用初始化器
    applyInitializers(context);
    // 触发Spring Boot启动过程的contextPrepared事件
    listeners.contextPrepared(context);
    if (this.logStartupInfo) {
        logStartupInfo(context.getParent() == null);
        logStartupProfileInfo(context);
    }
    // 添加两个Spring Boot中的特殊单例Beans - springApplicationArguments以及springBootBanner
    context.getBeanFactory().registerSingleton("springApplicationArguments",
            applicationArguments);
    if (printedBanner != null) {
        context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
    }
    // 加载sources - 对于DemoApplication而言,这里的sources集合只包含了它一个class对象
    Set<Object> sources = getSources();
    Assert.notEmpty(sources, "Sources must not be empty");
    // 加载动作 - 构造BeanDefinitionLoader并完成Bean定义的加载
    load(context, sources.toArray(new Object[sources.size()]));
    // 触发Spring Boot启动过程的contextLoaded事件
    listeners.contextLoaded(context);
}

After, refreshContext (context) refresh context.

After, afterRefresh (context, applicationArguments), post-processing context

Since then, the entire startup process is complete, the entire process SpringApplicationRunListeners acts as an intermediary role, constantly passing event, context startup process of continuous Listeners call for event broadcasting, processed to the corresponding listener.

 

1, Spring in the Run Listeners and Application Listeners monitor the difference?

SpringApplicationRunListener

 

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/qq_36931982/article/details/84104268