/** * Create a new {@link SpringApplication} instance. The application context will load * beans from the specified primary sources (see {@link SpringApplication class-level} * documentation for details. The instance can be customized before calling * {@link #run(String...)}. * @param primarySources the primary bean sources * @see #run(Class, String[]) * @see #SpringApplication(ResourceLoader, Class...) * @see #setSources(Set) */ publicSpringApplication(Class<?>... primarySources) { this(null, primarySources); }
/** * Create a new {@link SpringApplication} instance. The application context will load * beans from the specified primary sources (see {@link SpringApplication class-level} * documentation for details. The instance can be customized before calling * {@link #run(String...)}. * @param resourceLoader the resource loader to use * @param primarySources the primary bean sources * @see #run(Class, String[]) * @see #setSources(Set) 传入进来的参数 : 可以传入进来的 resourceLoader的值是null, primarySources : BootSourceLearnApplication.class */ @SuppressWarnings({ "unchecked", "rawtypes" }) publicSpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { // this.resourceLoader的值在这里目前也是 null. this.resourceLoader = resourceLoader; // 对传入进来的 primarySources参数进行检验,如果是null的话,这里是会有异常抛出来的,当然了,有异常的话,那么程序在这里自然也就会终止了. Assert.notNull(primarySources, "PrimarySources must not be null"); // 将primarySources传入LinkedHashSet的集合中,并且赋值给this.primarySources. this.primarySources = newLinkedHashSet<>(Arrays.asList(primarySources)); // org.springframework.boot.WebApplicationType , 枚举类, 这里返回的是 SERVLET this.webApplicationType = WebApplicationType.deduceFromClasspath(); // 返回回来的 instances 集合 赋值给 this.initializers 参数 setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); // 这个与上面的 getSpringFactoriesInstances(ApplicationContextInitializer.class) 是一样的,只是去根据条件传入的参数值不一样,自然其获取出来的值也是不一样的,只不过的是,这步我们是从cache中获取出来的,也就是说,其实在上一步调用这个方法的时候,就已经将这次的值也给获取出来了,并且放入到了cache的缓存Map中,所以这次获取是直接从cache中获取出来的. 然后赋值给 this.listeners 参数 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); // 这里根据 "main".equals(stackTraceElement.getMethodName())进行判断获取 MainApplicationClass. 这里我们就已经将启动类的构造函数给看完了. this.mainApplicationClass = deduceMainApplicationClass(); }
/** * Load the fully qualified class names of factory implementations of the * given type from {@value #FACTORIES_RESOURCE_LOCATION}, using the given * class loader. * @param factoryType the interface or abstract class representing the factory * @param classLoader the ClassLoader to use for loading resources; can be * {@code null} to use the default * @throws IllegalArgumentException if an error occurs while loading factory names * @see #loadFactories */ publicstatic List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) { // factoryTypeName : org.springframework.context.ApplicationContextInitializer // StringfactoryTypeName= factoryType.getName(); // loadSpringFactories(classLoader) 获取 META-INF/spring.factories下的一些配置信息,然后读取的内容将其封装成一个集合, getOrDefault方法,如果获取出来,有的话,就是用有的,没有的话,就返回一个空的集合. return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList()); }