蛋糕网站设计,抖音电商培训,建设部网站备案,沧州百度建设网站我们今天就来点实战#xff0c;总结一下除了烂大街的Value和ConfigurationProperties外#xff0c;还有哪些读取yml配置文件的方法#xff1f;1、Environment在Spring中有一个类Environment#xff0c;它可以被认为是当前应用程序正在运行的环境#xff0c;它继承了Proper… 我们今天就来点实战总结一下除了烂大街的Value和ConfigurationProperties外还有哪些读取yml配置文件的方法1、Environment在Spring中有一个类Environment它可以被认为是当前应用程序正在运行的环境它继承了PropertyResolver接口因此可以作为一个属性解析器使用。先创建一个yml文件属性如下person:name: hydragender: maleage: 18使用起来也非常简单直接使用Autowired就可以注入到要使用的类中然后调用它的getProperty()方法就可以根据属性名称取出对应的值了。RestController
public class EnvironmentController {Autowiredprivate Environment environment;GetMapping(envTest)private void getEnv(){System.out.println(environment.getProperty(person.name));System.out.println(environment.getProperty(person.gender));Integer autoClose environment.getProperty(person.age, Integer.class);System.out.println(autoClose);String defaultValue environment.getProperty(person.other, String.class, defaultValue);System.out.println(defaultValue);}
}在上面的例子中可以看到除了简单的获取外Environment提供的方法还可以对取出的属性值进行类型转换、以及默认值的设置调用一下上面的接口打印结果如下hydra
male
18
defaultValue除了获取属性外还可以用来判断激活的配置文件我们先在application.yml中激活pro文件spring:profiles:active: pro可以通过acceptsProfiles方法来检测某一个配置文件是否被激活加载或者通过getActiveProfiles方法拿到所有被激活的配置文件。测试接口GetMapping(getActiveEnv)
private void getActiveEnv(){System.out.println(environment.acceptsProfiles(pro));System.out.println(environment.acceptsProfiles(dev));String[] activeProfiles environment.getActiveProfiles();for (String activeProfile : activeProfiles) {System.out.println(activeProfile);}
}打印结果true
false
pro2、YamlPropertiesFactoryBean在Spring中还可以使用YamlPropertiesFactoryBean来读取自定义配置的yml文件而不用再被拘束于application.yml及其激活的其他配置文件。在使用过程中只需要通过setResources()方法设置自定义yml配置文件的存储路径再通过getObject()方法获取Properties对象后续就可以通过它获取具体的属性下面看一个例子GetMapping(fcTest)
public void ymlProFctest(){YamlPropertiesFactoryBean yamlProFb new YamlPropertiesFactoryBean();yamlProFb.setResources(new ClassPathResource(application2.yml));Properties properties yamlProFb.getObject();System.out.println(properties.get(person2.name));System.out.println(properties.get(person2.gender));System.out.println(properties.toString());
}查看运行结果可以读取指定的application2.yml的内容susan
female
{person2.age18, person2.genderfemale, person2.namesusan}但是这样的使用中有一个问题那就是只有在这个接口的请求中能够取到这个属性的值如果再写一个接口不使用YamlPropertiesFactoryBean读取配置文件即使之前的方法已经读取过这个yml文件一次了第二个接口取到的仍然还是空值。来对这个过程进行一下测试Value(${person2.name:null})
private String name;
Value(${person2.gender:null})
private String gender;GetMapping(fcTest2)
public void ymlProFctest2(){System.out.println(name);System.out.println(gender);
}先调用一次fcTest接口再调用fcTest2接口时会打印null值null
null想要解决这个问题也很简单可以配合PropertySourcesPlaceholderConfigurer使用它实现了BeanFactoryPostProcessor接口也就是一个bean工厂后置处理器的实现可以将配置文件的属性值加载到一个Properties文件中。使用方法如下Configuration
public class PropertyConfig {Beanpublic static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {PropertySourcesPlaceholderConfigurer configurer new PropertySourcesPlaceholderConfigurer();YamlPropertiesFactoryBean yamlProFb new YamlPropertiesFactoryBean();yamlProFb.setResources(new ClassPathResource(application2.yml));configurer.setProperties(yamlProFb.getObject());return configurer;}
}再次调用之前的接口结果如下可以正常的取到application2.yml中的属性susan
female除了使用YamlPropertiesFactoryBean将yml解析成Properties外其实我们还可以使用YamlMapFactoryBean解析yml成为Map使用方法非常类似GetMapping(fcMapTest)
public void ymlMapFctest(){YamlMapFactoryBean yamlMapFb new YamlMapFactoryBean();yamlMapFb.setResources(new ClassPathResource(application2.yml));MapString, Object map yamlMapFb.getObject();System.out.println(map);
}打印结果{person2{namesusan, genderfemale, age18}}3、监听事件在上篇介绍原理的文章中我们知道SpringBoot是通过监听事件的方式来加载和解析的yml文件那么我们也可以仿照这个模式来加载自定义的配置文件。首先定义一个类实现ApplicationListener接口监听的事件类型为ApplicationEnvironmentPreparedEvent并在构造方法中传入要解析的yml文件名public class YmlListener implements ApplicationListenerApplicationEnvironmentPreparedEvent {private String ymlFilePath;public YmlListener(String ymlFilePath){this.ymlFilePath ymlFilePath;}//...
}自定义的监听器中需要实现接口的onApplicationEvent()方法当监听到ApplicationEnvironmentPreparedEvent事件时会被触发Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {ConfigurableEnvironment environment event.getEnvironment();ResourceLoader loader new DefaultResourceLoader();YamlPropertySourceLoader ymlLoader new YamlPropertySourceLoader();try {ListPropertySource? sourceList ymlLoader.load(ymlFilePath, loader.getResource(ymlFilePath));for (PropertySource? propertySource : sourceList) {environment.getPropertySources().addLast(propertySource);}} catch (IOException e) {e.printStackTrace();}
}上面的代码中主要实现了获取当前环境Environment当ApplicationEnvironmentPreparedEvent事件被触发时已经完成了Environment的装载并且能够通过event事件获取通过YamlPropertySourceLoader加载、解析配置文件将解析完成后的OriginTrackedMapPropertySource添加到Environment中修改启动类在启动类中加入这个监听器public static void main(String[] args) {SpringApplication application new SpringApplication(MyApplication.class);application.addListeners(new YmlListener(classpath:/application2.yml));application.run(args);
}在向environment中添加propertySource前加一个断点查看环境的变化执行完成后可以看到配置文件源已经被添加到了环境中启动完成后再调用一下接口查看结果susan
female能够正确的取到配置文件中的值说明自定义的监听器已经生效。4、SnakeYml前面介绍的几种方式在Spring环境下无需引入其他依赖就可以完成的接下来要介绍的SnakeYml在使用前需要引入依赖但是同时也可以脱离Spring环境单独使用。先引入依赖坐标dependencygroupIdorg.yaml/groupIdartifactIdsnakeyaml/artifactIdversion1.23/version
/dependency准备一个yml配置文件person1:name: hydragender: male
person2:name: susangender: female在使用SnakeYml解析yml时最常使用的就是load、loadlAll、loadAs方法这三个方法可以加载yml文件或字符串最后返回解析后的对象。我们先从基础的load方法开始演示public void test1(){Yaml yamlnew Yaml();MapString, Object map yaml.load(getClass().getClassLoader().getResourceAsStream(snake1.yml));System.out.println(map);
}运行上面的代码打印Map中的内容{person1{namehydra, gendermale}, person2{namesusan, genderfemale}}接下来看一下loadAll方法它可以用来加载yml中使用---连接符连接的多个文档将上面的yml文件进行修改person1:name: hydragender: male
---
person2:name: susangender: female在添加了连接符后尝试再使用load方法进行解析报错如下显示发现了另一段yml文档从而无法正常解析这时候修改上面的代码使用loadAll方法public void test2(){Yaml yamlnew Yaml();IterableObject objects yaml.loadAll(getClass().getClassLoader().getResourceAsStream(snake2.yml));for (Object object : objects) {System.out.println(object);}
}执行结果如下{person1{namehydra, gendermale}}
{person2{namesusan, genderfemale}}可以看到loadAll方法返回的是一个对象的迭代里面的每个对象对应yml中的一段文档修改后的yml文件就被解析成了两个独立的Map。接下来再来看一下loadAs方法它可以在yml解析过程中指定类型直接封装成一个对象。我们直接复用上面的snake1.yml在解析前先创建两个实体类对象用于接收Data
public class Person {SinglePerson person1;SinglePerson person2;
}Data
public class SinglePerson {String name;String gender;
}下面使用loadAs方法加载yml注意方法的第二个参数就是用于封装yml的实体类型。public void test3(){Yaml yamlnew Yaml();Person person yaml.loadAs(getClass().getClassLoader().getResourceAsStream(snake1.yml), Person.class);System.out.println(person.toString());
}查看执行结果Person(person1SinglePerson(namehydra, gendermale), person2SinglePerson(namesusan, genderfemale))实际上如果想要将yml封装成实体对象也可以使用另一种方法。在创建Yaml对象的时候传入一个指定实体类的构造器对象然后直接调用load方法就可以实现public void test4(){Yaml yamlnew Yaml(new Constructor(Person.class));Person person yaml.load(getClass().getClassLoader().getResourceAsStream(snake1.yml));System.out.println(person.toString());
}执行结果与上面相同Person(person1SinglePerson(namehydra, gendermale), person2SinglePerson(namesusan, genderfemale))SnakeYml其实实现了非常多的功能这里就不一一列举了有兴趣的小伙伴可以自己查看一下文档。如果你看了上一篇的文章后跟着翻阅了一下源码那么你会发现其实在SpringBoot的底层也是借助了SnakeYml来进行的yml的解析操作。5、jackson-dataformat-yaml相比大家平常用jackson比较多的场景是用它来处理json其实它也可以用来处理yml使用前需要引入依赖dependencygroupIdcom.fasterxml.jackson.dataformat/groupIdartifactIdjackson-dataformat-yaml/artifactIdversion2.12.3/version
/dependency使用jackson读取yml也非常简单这里用到了常用的ObjectMapper在创建ObjectMapper对象时指定使用YAML工厂之后就可以简单的将yml映射到实体public void read() throws IOException {ObjectMapper objectMapper new ObjectMapper(new YAMLFactory());InputStream input new FileInputStream(F:\\Work\\yml\\src\\main\\resources\\snake1.yml);Person person objectMapper.readValue(input, Person.class);System.out.println(person.toString());
}运行结果Person(person1SinglePerson(namehydra, gendermale), person2SinglePerson(namesusan, genderfemale))如果想要生成yml文件的话可以调用ObjectMapper的writeValue方法实现public void write() throws IOException {MapString,Object mapnew HashMap();SinglePerson person1 new SinglePerson(Trunks, male);SinglePerson person2 new SinglePerson(Goten, male);Person personnew Person(person1,person2);map.put(person,person);ObjectMapper objectMapper new ObjectMapper(new YAMLFactory());objectMapper.writeValue(new File(F:\\Work\\yml\\src\\main\\resources\\jackson-gen.yml),map);
}查看生成的yml文件可以看到jackson对字符串类型严格的添加了引号还在文档的开头添加了yml的链接符。至于其他jackson读写yml的复杂功能大家可以在工作中自己去探索使用。总结本文介绍了5种读取yml配置文件的方式前3种依赖于Spring环境而SnakeYml和Jackson则可以脱离环境独立使用可以说它们是对Value和ConfigurationProperties注解使用的补充。这几种方法的使用场景不同也各有各的有优点各自具备一些特殊的用法而我们在工作中更多情况下要根据具体的用途进行一种方案的选取或多种的搭配使用。好了希望这篇实战能够帮助到大家我们下篇再见。记得一键三连哦。往期推荐Spring Boot Admin贼好使扯一把 Spring 的三种注入方式到底哪种注入方式最佳SpringCloud组件Ribbon负载均衡策略及执行原理