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
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"); }
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(); }
@Value("${system.systemName}") private String systemName;
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; }
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!