Maison  >  Article  >  Java  >  Comment mettre à jour dynamiquement les fichiers yml dans SpringBoot

Comment mettre à jour dynamiquement les fichiers yml dans SpringBoot

WBOY
WBOYavant
2023-05-12 16:22:061134parcourir

Dépendance du projet

Le projet est basé sur la version 2.0.0.RELEASE, donc Snakeyaml doit être introduit séparément et les versions supérieures sont incluses

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

La plupart des méthodes sur Internet Le composant de configuration spring-cloud-context est introduit pour appeler la méthode d'actualisation de ContextRefresher pour obtenir le même effet. Considérez les deux points suivants qui ne sont pas utilisés

  • #🎜🎜. #Le framework de développement utilise les journaux de connexion et introduit spring -cloud-context provoquera des erreurs de lecture de configuration des journaux

  • L'introduction de spring-cloud-context introduira également le spring-boot- composant démarreur-actionneur, qui ouvrira certaines vérifications de l'état. Le routage et les ports nécessitent un contrôle supplémentaire sur la sécurité du framework sous les fichiers de ressources nécessite l'utilisation de ClassPathResource Get 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 file content update
Après avoir obtenu le contenu du fichier yml, nous l'affichons visuellement à la réception pour modification de l'affichage , et convertissez le contenu modifié en structure Map, puis utilisez yaml.dumpAsMap pour le convertir en flux et l'écrire dans le fichier

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

actualisation de l'attribut YML

Il y a généralement trois façons de lire et d'utiliser les attributs yml dans le programme

    @Value("${system.systemName}")
    private String systemName;

Propertyfresh

La collection de configurations que nous lisons via la méthode Environment.getProperty est en fait stockée dans PropertySources. Il nous suffit de supprimer toutes les paires clé-valeur et de les stocker. dans le propertyMap, et convertissez le contenu du fichier yml mis à jour en un ymlMap du même format, fusionnez les deux Maps et appelez la méthode replace de PropertySources pour un remplacement global

Cependant, la déconstruction des données de le ymlMap après yaml.load et le propertyMap extrait par PropertySources sont différents et une conversion manuelle est requise# 🎜🎜#

La collection propertyMap est une simple paire clé-valeur clé-valeur. forme de propriétés. Par exemple, la collection system.systemName=>xxxxx Group Management System

ymlMap est la clé de la hiérarchie imbriquée de LinkedHashMap, par exemple system=>(systemName=>xxxxx Group Management System. )

La méthode de conversion est la suivante

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

La méthode d'actualisation est la suivante

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

Annotation Refresh

Que ce soit il s'agit de l'annotation Value ou de l'annotation ConfigurationProperties, elles sont en fait utilisées en injectant la méthode attribut de l'objet Bean. On personnalise d'abord l'annotation RefreshValue pour modifier la classe du Bean où se trouve l'attribut#🎜 🎜#

. En implémentant l'interface InstantiationAwareBeanPostProcessorAdapter, les beans correspondants sont filtrés et stockés au démarrage du système. Lors de la mise à jour du fichier yml, les propriétés du

bean correspondantes peuvent être mises à jour via la notification d'événement de Spring lors de la mise à jour du fichier yml#🎜. 🎜 #

Enregistrer les événements à l'aide des annotations EventListener

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

Les événements déclencheurs de notification utilisent la méthode submitEvent d'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));

Le code complet de YamlConfigRefreshPostProcessor est le suivant

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer