Spring Application实例化流程和构造方法参数( 二 )

... primarySources) {this(nu1l, primarySources);@SuppressWarnings({ "unchecked", "rawtypes" })public SpringApplication(ResourceLoader resourceLoader, Class... primarySources)this. resourceLoader = resourceLoader;Assert . notNull(primarySources, "PrimarySources must not be null");this . primarySources = new LinkedHashSet<> (Arrays . asList(primarySources));//推断 web 应用类型this . webApplicationType = WebApplicationType. deduceF romClasspath();//加戴并初始化 Appl icationContextInitial izer 及相关实现类setInitializers((Collection)getSpringFactoriesInstances (ApplicationContextInitializer.class));//加戴并初始化 Appl icationL istener 及相关实现类setListeners((Collection) getSpringFactoriesInstances (ApplicationListener.class));//推断 main 方法 Class 类this . mainApplicationClass = deduceMainApplicationClass();}SpringApplication 提供了两个构造方法 , 核心业务逻辑在第二个构造方法中实现 , 在后面章节我们会从构造方法中的具体实现入手进行详细讲解 , 先来了解 SpringApplication 的初始化过程 。
SpringApplication 构造方法参数SpringApplication 的核心构造方法有两个参数 , 第一个为 ResourceLoader resourcel oader,第二个 为 Class ResourceLoader 为资源加载的接口 , 在 Spring Boot 启动时打印对应的 banner 信息 , 默认采用的就是 DefaultResourceLoader 。实战过程中 , 如果程序未按照 Spring Boot 的“约定”将 banner 的内容放置于 classpath 下 , 或者文件名不是 banner.*格式 , 默认资源加载器是无法加载到对应的 banner 信息的 , 此时可通过 ResourceL oader 来指定需要加载的文件路径 。
第二个参数 Class.. .primarySources,为可变参数 , 默认传入 SpringBoot 入口类 。 如果作 为 项 目 的 引 导 类,此 参 数 传 入 的 类 需 要 满 足 一 个 条 件,就 是 被 注 解@EnableAutoConfiguration 或其组合注解标注 。 由于@SpringBootApplication 注解中包含了@EnableAutoConfiguration 注解 , 因此被@SpringBootApplication 注解标注的类也可作为参数传入 。 当然 , 该参数也可传入其他普通类 。 但只有传入被@EnableAutoConfiguration标注的类才能够开启 Spring Boot 的自动配置 。
下面我们以实例来演示以其他引导类为入口类进行的 Spring Boot 项目启动 。 先在入口类同级创建一个 OtherApplication 类 ,使用@SpringBootApplication 进行注解 。
@SpringBootApplicationpublic class OtherApplication {}然后在原来的入口类 SpringL earnApplication 的 main 方法中将 primarySources 参数的值由 SpringL earnApplication.class 替 换 为 OtherApplication.class, 并 将 SpringLearnApplication 类上的注解去掉 。
public class SpringLearnApplication {public static void main(String[] args) {new SpringApplication(OtherApplication. class). run(args);}执行 main 方法 , 程序依旧可完成自动配置 , 可以正常访问 。 因此 , 决定 Spring Boot 启动的入口类并不一定是 main 方法所在类 , 而是直接或间接被@EnableAutoConfiguration 标注的类 。 在此也证明了之前提到的@SpringBootApplication 和@EnableAutoConfiguration 入口并没有依赖关系 , 只是无论通过 new 创建 SpringApplication 对象再调用 run 方法或是通过 SpringApplication 的 run 方法来启动程序 , 都不离不开 primarySources 参数 。
同时 , 在 SpringApplication 类中还提供 了追加 primarySources 的方法 , 代码如下 。