多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 一、为什么要学加载外部配置文件 本节为大家介绍另外一种场景:有一些老的项目里面的jar包并未主动的去与spring boot 融合,很多jar包都有自己的配置文件。如果我们在spring boot项目中使用这些jar包就必须得使用它们的配置文件,那就面临一个问题:**我们的spring boot项目默认只有一个全局配置文件:application.yml或application.properties。该如何加载额外的配置文件?** 如何解决这个问题,就是本节将为大家介绍的内容。 ## 二、使用@PropertySource加载自定义yml或properties文件 #### 2.1.properties配置文件加载 `family.properties`这种格式的配置文件,使用如下的注解就可以将文件中的配置属性进行加载,非常简单! ~~~ @PropertySource(value = {"classpath:family.properties"}) public class Family { ~~~ #### 2.2.yaml配置文件加载 [spring 官方文档明确说明不支持使用@PropertySource加载YAML配置文件](https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-yaml-shortcomings),但是我们仍然有办法,跟着我继续。 ![](https://img.kancloud.cn/64/a6/64a63bd31fad31bb15c78b8231abe484_1204x77.png) * 我们新建一个配置文件family.yml,把上一节用到的YAML数据结构放里面。用来模拟第三方jar包的额外配置文件(非application配置文件)。 ~~~ # 1. 一个家庭有爸爸、妈妈、孩子。 # 2. 这个家庭有一个名字(family-name)叫做“happy family” # 3. 爸爸有名字(name)和年龄(age)两个属性 # 4. 妈妈有两个别名 # 5. 孩子除了名字(name)和年龄(age)两个属性,还有一个friends的集合 # 6. 每个friend有两个属性:hobby(爱好)和性别(sex) family: family-name: "happy family" father: name: zimug age: 18 mother: alias: - lovely - ailice child: name: zimug2 age: 5 friends: - hobby: football sex: male - hobby: basketball sex: female ~~~ * 笔者通过阅读代码了解到,DefaultPropertySourceFactory是进行配置文件加载的工厂类。 * 尽管其默认不支持读取YAML格式外部配置文件,但是我们可以通过继承DefaultPropertySourceFactory ,然后对它的createPropertySource进行一下改造。就可以实现YAML的“额外”配置文件加载。 ~~~ public class MixPropertySourceFactory extends DefaultPropertySourceFactory { @Override public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException { String sourceName = name != null ? name : resource.getResource().getFilename(); if (sourceName != null &&(sourceName.endsWith(".yml") || sourceName.endsWith(".yaml"))) { Properties propertiesFromYaml = loadYml(resource); //将YML配置转成Properties之后,再用PropertiesPropertySource绑定 return new PropertiesPropertySource(sourceName, propertiesFromYaml); } else { return super.createPropertySource(name, resource); } } //将YML格式的配置转成Properties配置 private Properties loadYml(EncodedResource resource) throws IOException{ YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean(); factory.setResources(resource.getResource()); factory.afterPropertiesSet(); return factory.getObject(); } } ~~~ * 然后基于上一节的代码,在Family类的上面加上如下注解即可。通过factory属性明确的指定使用我们自定义的MixPropertySourceFactory加载yml配置文件。 ~~~ @PropertySource(value = {"classpath:family.yml"}, factory = MixPropertySourceFactory.class) public class Family { ~~~ ## 三、使用@ImportResource加载Spring的xml配置文件 在没有Spring注解的时代,spring的相关配置都是通过xml来完成的,如:beans.xml。下面的XML配置的含义是:将com.zimug.bootlaunch.service.TestBeanService实例化并注入到Spring上下文环境中。 ~~~ <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="testBeanService" class="com.zimug.bootlaunch.service.TestBeanService"></bean> </beans> ~~~ * 新建一个空类,com.zimug.bootlaunch.service.TestBeanService。 * 测试用例,测试Spring上下文环境中是否有testBeanService这样一个bean,有的话表示xml配置文件已经生效,成功将testBeanService实例化并注入到Spring上下文环境中: ~~~ @RunWith(SpringRunner.class) @SpringBootTest public class ImportResourceTests { @Autowired private ConfigurableApplicationContext ioc; @Test public void testHelloService() { //测试Spring上下文环境中是否有testBeanService这样一个bean,有的话表示xml配置文件生效 boolean testBeanService= ioc.containsBean("testBeanService"); System.out.println(testBeanService); } } ~~~ * 因为还没使用@ImportResource加载beans.xml,此时执行测试用例,输出false表示beans.xml配置文件并未加载,所以没有testBeanService的存在 * 在spring boot应用入口启动类BootLauchApplication上加`@ImportResource(locations = {"classpath:beans.xml"})`,该注解用来加载Spring XML配置文件。 此时再试一下测试用例,输出:true。表示beans.xml配置文件被正确加载。