加载Spring的上下文启动流程
https://www.processon.com/embed/61cd2436e401fd7a538b36a7
解析:
@SpringBootTest标记了junit5的注解@ExtendWith(SpringExtension.class)
SpringExtension实现了junit5的test的生命周期的钩子函数,如BeforeAllCallback,TestInstancePostProcessor,BeforeEachCallback
在junit5的钩子函数中BeforeAllCallback会实例化TestContextManager
TestContextManager的钩子函数会解析@SpringBootTest的元注解@BootstrapWith(SpringBootTestContextBootstrapper.class),进而获取到关键类SpringBootContextLoader
TestContextManager也会通过spring的SPI机制解析meta-INF/spring.factories获取所有实现TestExecutionListener的接口实现类,
关键类ServletTestExecutionListener-针对servletweb类型
test生命周期钩子函数调用TestExecutionListener的方法,进而会触发执行ServletTestExecutionListener的setUpRequestContextIfNecessary
setUpRequestContextIfNecessary
会从缓存中获取ApplicationContext,没有最终调用SpringBootContextLoader.loadContext
加载spring的上下文
SpringBootContextLoader.loadContext会获取上面解析配置推测的类型,最终执行SpringApplication.run启动spring
boot加载spring的上下文
public class SpringBootContextLoader extends AbstractContextLoader {
public class SpringBootContextLoader extends AbstractContextLoader {
@Override
public ApplicationContext loadContext(MergedContextConfiguration config) throws Exception {
Class>[] configClasses = config.getClasses();
String[] configLocations = config.getLocations();
Assert.state(!ObjectUtils.isEmpty(configClasses) || !ObjectUtils.isEmpty(configLocations),
() -> "No configuration classes or locations found in @SpringApplicationConfiguration. "
+ "For default configuration detection to work you need Spring 4.0.3 or better (found "
+ SpringVersion.getVersion() + ").");
SpringApplication application = getSpringApplication();
application.setMainApplicationClass(config.getTestClass());
application.addPrimarySources(Arrays.asList(configClasses));
application.getSources().addAll(Arrays.asList(configLocations));
List> initializers = getInitializers(config, application);
if (config instanceof WebMergedContextConfiguration) {
application.setWebApplicationType(WebApplicationType.SERVLET);
if (!isEmbeddedWebEnvironment(config)) {
new WebConfigurer().configure(config, application, initializers);
}
}
else if (config instanceof ReactiveWebMergedContextConfiguration) {
application.setWebApplicationType(WebApplicationType.REACTIVE);
if (!isEmbeddedWebEnvironment(config)) {
application.setApplicationContextFactory(
ApplicationContextFactory.of(GenericReactiveWebApplicationContext::new));
}
}
else {
application.setWebApplicationType(WebApplicationType.NONE);
}
application.setInitializers(initializers);
ConfigurableEnvironment environment = getEnvironment(application, config.getActiveProfiles());
ResourceLoader resourceLoader = (application.getResourceLoader() != null) ? application.getResourceLoader()
: new DefaultResourceLoader(null);
TestPropertySourceUtils.addPropertiesFilesToEnvironment(environment, resourceLoader,
config.getPropertySourceLocations());
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(environment, getInlinedProperties(config));
application.setEnvironment(environment);
String[] args = SpringBootTestArgs.get(config.getContextCustomizers());
return application.run(args);
}
...
}



