Spring Boot技术内幕:架构设计与实现原理
上QQ阅读APP看书,第一时间看更新

3.3 SpringApplication构造方法参数

SpringApplication的核心构造方法有两个参数,第一个为ResourceLoader resourceLoader,第二个为Class<?>...primarySources。

ResourceLoader为资源加载的接口,在Spring Boot启动时打印对应的banner信息,默认采用的就是DefaultResourceLoader。实战过程中,如果程序未按照Spring Boot的“约定”将banner的内容放置于classpath下,或者文件名不是banner.*格式,默认资源加载器是无法加载到对应的banner信息的,此时可通过ResourceLoader来指定需要加载的文件路径。

第二个参数Class<?>...primarySources,为可变参数,默认传入Spring Boot入口类。如果作为项目的引导类,此参数传入的类需要满足一个条件,就是被注解@EnableAutoConfiguration或其组合注解标注。由于@SpringBootApplication注解中包含了@EnableAutoConfiguration注解,因此被@SpringBootApplication注解标注的类也可作为参数传入。当然,该参数也可传入其他普通类。但只有传入被@EnableAutoConfiguration标注的类才能够开启Spring Boot的自动配置。

下面我们以实例来演示以其他引导类为入口类进行的Spring Boot项目启动。先在入口类同级创建一个OtherApplication类,使用@SpringBootApplication进行注解。


@SpringBootApplication
public class OtherApplication {
}

然后在原来的入口类SpringLearnApplication的main方法中将primarySources参数的值由SpringLearnApplication.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的方法,代码如下。


public void addPrimarySources(Collection<Class<?>> additionalPrimarySources) {
    this.primarySources.addAll(additionalPrimarySources);
}

回到primarySources参数中,在实例化SpringApplication类过程中并没有对primarySources参数做过多处理,只是将其转化为Set集合,并赋值给SpringApplication的私有成员变量Set<Class<?>> primarySources,代码如下。


public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    ...
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    ...
}

注意SpringApplication的私有变量primarySources依旧为LinkedHashSet,它具有去重的特性。

至此,SpringApplication构造时参数赋值对应变量这一步便完成了。