SpringBoot Source Analysis: Creating object instances SpringApplication

Previous Article automated assembly resolved SpringBoot principle , we analyzed the principle of automatic assembly SpringBoot and @SpringBootApplicationprinciples annotations, this article will continue on the main articles in the method of analysis based on SpringApplicationthe class

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

Click runmethod to track down all the way, first of all to do it is find instantiate SpringApplicationan 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();
    }
  1. First look at the deduceWebApplicationTypemethod
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

  1. Load all ApplicationContextInitializerand ApplicationListenerthe 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 SpringFactoriesLoaderthis 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 Ordersorting value annotation

On the specific role of these implementation classes please pay attention to the follow-up article

  1. The last line is to find meaning class method main entrance is located, is assigned to a global variablemainApplicationClass

Guess you like

Origin www.cnblogs.com/zhixiang-org-cn/p/11569994.html