Rumah >Java >javaTutorial >Bagaimana untuk mengemas kini fail yml secara dinamik dalam SpringBoot
Projek ini berdasarkan versi 2.0.0.RELEASE, jadi snakeyaml perlu diperkenalkan secara berasingan dan versi yang lebih tinggi disertakan
<dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>1.23</version> </dependency>
Kebanyakan kaedah di Internet adalah untuk memperkenalkan spring-cloud Komponen konfigurasi -context memanggil kaedah refresh ContextRefresher untuk mencapai kesan yang sama Pertimbangkan dua perkara berikut:
Rangka kerja pembangunan menggunakan log balik spring-cloud-context akan menyebabkan bacaan konfigurasi log Dapatkan ralat
Memperkenalkan spring-cloud-context juga akan memperkenalkan komponen spring-boot-starter-actuator, yang akan membuka beberapa pemeriksaan kesihatan laluan dan pelabuhan, yang memerlukan kawalan tambahan ke atas keselamatan rangka kerja
Membaca fail di bawah fail sumber memerlukan penggunaan ClassPathResource untuk mendapatkan InputStream
rreeeSelepas kami memperoleh kandungan fail yml, kami memaparkannya secara visual ke meja depan untuk pengubahsuaian paparan, menukar kandungan yang diubah suai menjadi struktur Peta melalui kaedah yaml.load, dan kemudian gunakan yaml.dumpAsMap untuk menukarnya menjadi strim dan menulisnya pada fail
public String getTotalYamlFileContent() throws Exception { String fileName = "application.yml"; return getYamlFileContent(fileName); } public String getYamlFileContent(String fileName) throws Exception { ClassPathResource classPathResource = new ClassPathResource(fileName); return onvertStreamToString(classPathResource.getInputStream()); } public static String convertStreamToString(InputStream inputStream) throws Exception{ return IOUtils.toString(inputStream, "utf-8"); }
Secara amnya terdapat tiga cara untuk membaca dan menggunakan atribut yml dalam program
Gunakan anotasi Nilai
public void updateTotalYamlFileContent(String content) throws Exception { String fileName = "application.yml"; updateYamlFileContent(fileName, content); } public void updateYamlFileContent(String fileName, String content) throws Exception { Yaml template = new Yaml(); Map<String, Object> yamlMap = template.load(content); ClassPathResource classPathResource = new ClassPathResource(fileName); Yaml yaml = new Yaml(); //字符输出 FileWriter fileWriter = new FileWriter(classPathResource.getFile()); //用yaml方法把map结构格式化为yaml文件结构 fileWriter.write(yaml.dumpAsMap(yamlMap)); //刷新 fileWriter.flush(); //关闭流 fileWriter.close(); }
Baca melalui suntikan persekitaran
@Value("${system.systemName}") private String systemName;
Gunakan anotasi ConfigurationProperties Baca
@Autowired private Environment environment; environment.getProperty("system.systemName")
Koleksi konfigurasi yang kami baca melalui kaedah environment.getProperty sebenarnya disimpan dalam PropertySources Kami hanya perlu mengeluarkan semua pasangan nilai kunci dan menyimpannya dalam propertyMap Tukar kandungan fail yml yang dikemas kini kepada ymlMap dengan format yang sama, gabungkan dua Peta , dan panggil kaedah ganti PropertySources untuk penggantian keseluruhan
Tetapi kedua-dua ymlMap selepas yaml.load dan propertyMap yang diambil oleh penyahbinaan Data PropertySources adalah berbeza dan memerlukan penukaran manual
Koleksi propertyMap ialah kunci ringkas, pasangan nilai kunci nilai dan kunci ialah nama dalam bentuk sifat, seperti system.systemName=>xxxxx Sistem Pengurusan Kumpulan
koleksi ymlMap ialah kunci, hierarki bersarang bagi LinkedHashMap, contohnya system=>(systemName=>xxxxx Group Management System)
Kaedah penukaran adalah seperti berikut
@Component @ConfigurationProperties(prefix = "system") public class SystemConfig { private String systemName; }
Kaedah muat semula adalah seperti berikut
public HashMap<String, Object> convertYmlMapToPropertyMap(Map<String, Object> yamlMap) { HashMap<String, Object> propertyMap = new HashMap<String, Object>(); for (String key : yamlMap.keySet()) { String keyName = key; Object value = yamlMap.get(key); if (value != null && value.getClass() == LinkedHashMap.class) { convertYmlMapToPropertyMapSub(keyName, ((LinkedHashMap<String, Object>) value), propertyMap); } else { propertyMap.put(keyName, value); } } return propertyMap; } private void convertYmlMapToPropertyMapSub(String keyName, LinkedHashMap<String, Object> submMap, Map<String, Object> propertyMap) { for (String key : submMap.keySet()) { String newKey = keyName + "." + key; Object value = submMap.get(key); if (value != null && value.getClass() == LinkedHashMap.class) { convertYmlMapToPropertyMapSub(newKey, ((LinkedHashMap<String, Object>) value), propertyMap); } else { propertyMap.put(newKey, value); } } }
Sama ada anotasi Nilai atau anotasi ConfigurationProperties, ia sebenarnya digunakan dengan menyuntik kaedah atribut objek Bean Kami mula-mula menyesuaikan anotasi RefreshValue untuk mengubah suai kelas Bean di mana atribut itu berada terletak
Dengan melaksanakan antara muka InstantiationAwareBeanPostProcessorAdapter, kacang yang sepadan ditapis dan disimpan apabila sistem bermula apabila mengemas kini fail yml, kemas kini sifat
kacang yang sepadan melalui pemberitahuan acara musim bunga 🎜>
Daftar acara Gunakan anotasi EventListenerString name = "applicationConfig: [classpath:/" + fileName + "]"; MapPropertySource propertySource = (MapPropertySource) environment.getPropertySources().get(name); Map<String, Object> source = propertySource.getSource(); Map<String, Object> map = new HashMap<>(source.size()); map.putAll(source); Map<String, Object> propertyMap = convertYmlMapToPropertyMap(yamlMap); for (String key : propertyMap.keySet()) { Object value = propertyMap.get(key); map.put(key, value); } environment.getPropertySources().replace(name, new MapPropertySource(name, map));untuk memberitahu peristiwa pencetus Gunakan kaedah publishEvent ApplicationContext
@EventListener public void updateConfig(ConfigUpdateEvent configUpdateEvent) { if(mapper.containsKey(configUpdateEvent.key)){ List<FieldPair> fieldPairList = mapper.get(configUpdateEvent.key); if(fieldPairList.size()>0){ for (FieldPair fieldPair:fieldPairList) { fieldPair.updateValue(environment); } } } }Kod lengkap YamlConfigRefreshPostProcessor adalah seperti berikut
Atas ialah kandungan terperinci Bagaimana untuk mengemas kini fail yml secara dinamik dalam SpringBoot. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!