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

3.8 SpringApplication的定制化配置

前面我们学习了Spring Boot启动过程中构建SpringApplication所做的一系列初始化操作,这些操作都是Spring Boot默认配置的。如果在此过程中需要定制化配置,Spring Boot在SpringApplication类中也提供了相应的入口。但正常情况下,如果无特殊需要,采用默认配置即可。

针对定制化配置,Spring Boot提供了如基于入口类、配置文件、环境变量、命令行参数等多种形式。下面我们了解一下几种不同的配置形式。

3.8.1 基础配置

基础配置与在application.properties文件中的配置一样,用来修改Spring Boot预置的参数。比如,我们想在启动程序的时候不打印Banner信息,可以通过在application.properties文件中设置“spring.main.banner-mode=off”来进行关闭。当然,我们也可以通过SpringApplication提供的相关方法来进行同样的操作。以下是官方提供的关闭Banner的代码。


public static void main(String[] args) {
    SpringApplication app = new SpringApplication(MySpringConfiguration.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
}

除了前面讲到的setInitializers和setListeners方法之外,其他的Setter方法都具有类似的功能,比如我们可以通过setWebApplicationType方法来代替Spring Boot默认的自动类型推断。

针对这些Setter方法,Spring Boot还专门提供了流式处理类SpringApplicationBuilder,我们将它的功能与SpringApplication逐一对照,可知SpringApplicationBuilder的优点是使代码更加简洁、流畅。

其他相同配置形式的功能就不再赘述了,我们可通过查看源代码进行进一步的学习。出于集中配置、方便管理的思路,不建议大家在启动类中配置过多的参数。比如,针对Banner的设置,我们可以在多处进行配置,但为了方便管理,尽可能的统一在application.properties文件中。

3.8.2 配置源配置

除了直接通过Setter方法进行参数的配置,我们还可以通过设置配置源参数对整个配置文件或配置类进行配置。我们可通过两个途径进行配置:SpringApplication构造方法参数或SpringApplication提供的setSources方法来进行设置。

在3.3节SpringApplication构造方法参数中已经讲到可以通过Class<?>...primarySources参数来配置普通类。因此,配置类可通过SpringApplication的构造方法来进行指定。但这种方法有一个弊端就是无法指定XML配置和基于package的配置。

另外一种配置形式为直接调用setSources方法来进行设置,方法源代码如下。


private Set<String> sources = new LinkedHashSet<>();

public void setSources(Set<String> sources) {
    Assert.notNull(sources, "Sources must not be null");
    this.sources = new LinkedHashSet<>(sources);
}

该方法的参数为String集合,可传递类名、package名称和XML配置资源。下面我们以类名为例进行演示。

WithoutAnnoConfiguration配置类代码如下。


public class WithoutAnnoConfiguration {

    public WithoutAnnoConfiguration(){
        System.out.println("WithoutAnnoConfiguration 对象被创建");
    }

    @Value("${admin.name}")
    private String name;

    @Value("${admin.age}")
    private int age;

    // 省略getter/setter方法
}

使用该配置的实例代码如下。


public static void main(String[] args) {
    SpringApplication app = new SpringApplication(SpringLearnApplication.class);
    Set<String> set = new HashSet<>();
    set.add(WithoutAnnoConfiguration.class.getName());
    app.setSources(set);
    ConfigurableApplicationContext context = app.run(args);
    WithoutAnnoConfiguration bean = context.getBean(WithoutAnnoConfiguration.class);
    System.out.println(bean.getName());
}

运行程序,我们在日志中即可看到已经获取到对应类的属性值。

无论是通过构造参数的形式还是通过Setter方法的形式对配置源信息进行指定,在Spring Boot中都会将其合并。SpringApplication类中提供了一个getAllSources方法,能够将两者参数进行合并。


public Set<Object> getAllSources() {
    // 创建去除的LinkedHashSet
    Set<Object> allSources = new LinkedHashSet<>();
    // primarySources不为空则加入Set
    if (!CollectionUtils.isEmpty(this.primarySources)) {
        allSources.addAll(this.primarySources);
    }
    // sources不为空则加入Set
    if (!CollectionUtils.isEmpty(this.sources)) {
        allSources.addAll(this.sources);
    }
    // 对Set进行包装,变为不可变的Set
    return Collections.unmodifiableSet(allSources);
}

关于SpringApplication类指定配置及配置源就讲到这里,更多相关配置信息可参考对应章节进行学习。