Previous Article automated assembly resolved SpringBoot principle , we analyzed the principle of automatic assembly SpringBoot and
@SpringBootApplication
principles annotations, this article will continue on the main articles in the method of analysis based onSpringApplication
the class
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Click run
method to track down all the way, first of all to do it is find instantiate SpringApplication
an object instance
public static ConfigurableApplicationContext run(Class<?> primarySource,
String... args) {
return run(new Class<?>[] { primarySource }, args);
}
public static ConfigurableApplicationContext run(Class<?>[] primarySources,
String[] args) {
return new SpringApplication(primarySources).run(args);
}
public SpringApplication(Class<?>... primarySources) {
this(null, primarySources);
}
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = deduceWebApplicationType();
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
- First look at the
deduceWebApplicationType
method
private WebApplicationType deduceWebApplicationType() {
if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null)) {
return WebApplicationType.REACTIVE;
}
for (String className : "javax.servlet.Servlet", org.springframework.web.context.ConfigurableWebApplicationContext") {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}
}
Probably means that according to several class exists above the current project to infer the current web environment, because here SpringBoot web framework is used by default SpringMVC, so the final result is returnedWebApplicationType.SERVLET
- Load all
ApplicationContextInitializer
andApplicationListener
the implementation class
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
Can be seen mainly use SpringFactoriesLoader
this class to load these two interface implementation class, the class is loaded into the embodiment using reflection later construct instances of these classes and implement those classes in accordance with the Order
sorting value annotation
On the specific role of these implementation classes please pay attention to the follow-up article
- The last line is to find meaning class method main entrance is located, is assigned to a global variable
mainApplicationClass