Heim  >  Artikel  >  Java  >  So aktualisieren Sie YML-Dateien dynamisch in SpringBoot

So aktualisieren Sie YML-Dateien dynamisch in SpringBoot

WBOY
WBOYnach vorne
2023-05-12 16:22:061134Durchsuche

Projektabhängigkeiten

Das Projekt basiert auf Version 2.0.0.RELEASE, daher muss Snakeyaml separat eingeführt werden und höhere Versionen sind enthalten

        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.23</version>
        </dependency>

Die meisten Methoden im Internet dienen der Einführung der Spring-Cloud-Context-Konfigurationskomponente und Rufen Sie die Aktualisierungsmethode von ContextRefresher auf, um dies zu erreichen. Berücksichtigen Sie für den gleichen Effekt die folgenden zwei Punkte, die nicht verwendet werden: Das Entwicklungsframework verwendet Logback-Protokolle. Die Einführung von Spring-Cloud-Kontext führt zu Fehlern beim Lesen der Protokollkonfiguration Durch die Einführung von Spring-Cloud-Context wird auch die Spring-Boot-Starter-Aktuator-Komponente eingeführt, die einige Gesundheitsprüfungsrouten und -ports öffnet, was eine zusätzliche Kontrolle über die Framework-Sicherheit erfordert ClassPathResource zum Abrufen von InputStream

    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");
    }
    YML-Dateien Inhaltsaktualisierung
  • Nachdem wir den Inhalt der YML-Datei erhalten haben, zeigen wir ihn visuell an der Rezeption zur Anzeigeänderung an. Wir konvertieren den geänderten Inhalt über die yaml.load-Methode in eine Kartenstruktur , und verwenden Sie dann yaml.dumpAsMap, um es in einen Stream zu konvertieren und in die Datei zu schreiben durch Umgebungsinjektion

        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();
        }
  • Verwenden Sie die Annotation „ConfigurationProperties“ zum Lesen
  •     @Value("${system.systemName}")
        private String systemName;

    Property-Aktualisierung

  • Wir lesen die Methode „environment.getProperty“ durch. Die abgerufene Konfigurationssammlung wird tatsächlich in PropertySources gespeichert. Wir müssen nur alle Schlüssel-Wert-Paare abrufen und in propertyMap speichern Konvertieren Sie den Inhalt der aktualisierten YML-Datei in eine YMLMap desselben Formats, führen Sie die beiden Maps zusammen und rufen Sie die Methode zum Ersetzen von PropertySources auf. Sie können die Methode als Ganzes ersetzen

Aber die Datendekonstruktion der YMLMap erfolgt nach yaml.load und der PropertyMap out by PropertySources sind unterschiedlich und eine manuelle Konvertierung ist erforderlich

Die PropertyMap-Sammlung ist ein einfaches Schlüssel-Wert-Schlüssel-Wert-Paar, und der Schlüssel hat die Form eines Eigenschaftennamens, zum Beispiel system.systemName=>xxxxx Group Management System

ymlMap-Sammlung ist der Schlüssel, die verschachtelte Hierarchie von LinkedHashMap, zum Beispiel system=>(systemName=>xxxxx Group Management System)

Die Konvertierungsmethode ist wie folgt

    @Autowired
    private Environment environment;
    environment.getProperty("system.systemName")

Die Aktualisierungsmethode ist wie folgt

@Component
@ConfigurationProperties(prefix = "system")
public class SystemConfig {
    private String systemName;
}

Annotation-Aktualisierung

Ob es sich um die Value-Annotation oder die ConfigurationProperties-Annotation handelt, sie wird tatsächlich durch Einfügen der Attributmethode des Bean-Objekts verwendet. Wir passen zunächst die Annotation RefreshValue an, um die Klasse der Bean zu ändern, in der sich das Attribut befindet Durch die Implementierung von InstantiationAwareBeanPostProcessorAdapter werden die entsprechenden Beans beim Systemstart gefiltert und gespeichert. Aktualisieren Sie die Eigenschaften der entsprechenden

Bean über die Ereignisbenachrichtigung von Spring.

  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);
            }
        }
    }

Das Notification-Trigger-Ereignis verwendet die PublishEvent-Methode von ApplicationContext

        String 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));

Der vollständige Code von YamlConfigRefreshPostProcessor lautet wie folgt

    @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);
                }
            }
        }
    }

Das obige ist der detaillierte Inhalt vonSo aktualisieren Sie YML-Dateien dynamisch in SpringBoot. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen