1. 概述
在设计Spring Boot应用时,我们通常希望使用外部配置来定义应用程序属性。这样可以在不同的环境中复用代码。有时,我们可能希望在一个环境中使用多个YAML配置文件。
在这个教程中,我们将学习两种在创建Spring Boot应用时加载多个YAML配置文件的方法。
2. 使用Spring Profile
将多个YAML配置文件包含在应用中的一个方法是使用Spring Profile。
这种方法利用了Spring自动加载与应用Profile相关的YAML配置文件的功能。
接下来,让我们通过一个例子来进行说明,涉及两个.yml
文件。
2.1. YAML设置
我们的第一个文件列出了学生。我们将其命名为application-students.yml
,并放在./src/main/resources
目录下:
students:
- Jane
- Michael
第二个文件名为application-teachers.yml
,也放在同一个./src/main/resources
目录下:
teachers:
- Margo
- Javier
2.2. 应用
现在,我们来搭建示例应用。我们将使用应用中的[*CommandLineRunner*](/spring-boot-console-app#console-application)
来看配置文件的加载情况:
@SpringBootApplication
public class MultipleYamlApplication implements CommandLineRunner {
@Autowired
private MultipleYamlConfiguration config;
public static void main(String[] args) {
SpringApplication springApp = new SpringApplication(MultipleYamlApplication.class);
springApp.setAdditionalProfiles("students", "teachers");
springApp.run(args);
}
public void run(String... args) throws Exception {
System.out.println("Students: " + config.getStudents());
System.out.println("Teachers: " + config.getTeachers());
}
}
在这个例子中,我们通过setAdditionalProfiles()
方法程序式地设置额外的Spring Profile。
我们也可以在通用的application.yml
文件中使用spring.profiles.include
参数:
spring:
profiles:
include:
- teachers
- students
这两种方法都可以设置Profile,在应用启动时,Spring会加载符合application-{profile}.yml
模式的任何YAML配置文件。
2.3. 配置
为了完成这个例子,让我们创建配置类。它会从YAML文件加载属性:
@Configuration
@ConfigurationProperties
public class MultipleYamlConfiguration {
List<String> teachers;
List<String> students;
// standard setters and getters
}
运行应用后,让我们检查日志:
c.b.p.m.MultipleYamlApplication : The following 2 profiles are active: "teachers", "students"
输出如下:
Students: [Jane, Michael]
Teachers: [Margo, Javier]
尽管这种方法有效,但它的缺点是使用了Spring Profile功能,这可能并不是Spring实现的初衷。
考虑到这一点,让我们来看看另一种更稳健的方法,用于加载多个YAML文件。
3. 使用@PropertySources
我们可以通过@PropertySources
注解和使用@PropertySource
加载YAML来指定多个YAML配置文件。
3.1. 应用
让我们用类似的应用再试一次:
@SpringBootApplication
public class MultipleYamlApplication implements CommandLineRunner {
@Autowired
private MultipleYamlConfiguration config;
public static void main(String[] args) {
SpringApplication.run(MultipleYamlApplication.class);
}
public void run(String... args) throws Exception {
System.out.println("Students: " + config.getStudents());
System.out.println("Teachers: " + config.getTeachers());
}
}
需要注意的是,此例中我们没有设置Spring Profile。
3.2. Configuration
和PropertySourceFactory
现在,让我们实现配置类:
@Configuration
@ConfigurationProperties
@PropertySources({
@PropertySource(value = "classpath:application-teachers.yml", factory = MultipleYamlPropertySourceFactory.class),
@PropertySource(value = "classpath:application-students.yml", factory = MultipleYamlPropertySourceFactory.class)})
public class MultipleYamlConfiguration {
List<String> teachers;
List<String> students;
// standard setters and getters
}
@PropertySources
注解包括了我们希望在应用中使用的每个YAML文件的@PropertySource
。factory
是一个自定义的PropertySourceFactory
,它允许加载YAML文件:
public class MultipleYamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) throws IOException {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(encodedResource.getResource());
Properties properties = factory.getObject();
return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
}
}
运行我们的MultipleYamlApplication
,我们可以看到预期的输出:
Students: [Jane, Michael]
Teachers: [Margo, Javier]
4. 总结
在这篇文章中,我们探讨了在Spring Boot应用中加载多个YAML配置文件的两种可能方法。
如往常一样,我们的示例代码的完整源码可以在GitHub上找到。