ホームページ >Java >&#&チュートリアル >SpringBoot で yml ファイルを動的に更新する方法
プロジェクトはバージョン 2.0.0.RELEASE に基づいているため、snakeyaml を別途導入する必要があり、より高いバージョンが含まれています
<dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>1.23</version> </dependency>
インターネット上のほとんどのメソッドは、 spring-cloud の導入 -context 構成コンポーネントは、同じ効果を達成するために ContextRefresher の更新メソッドを呼び出します。使用されていない次の 2 つの点を考慮してください。
開発フレームワークはログバック ログを使用します。 spring-cloud-context を導入すると、ログ設定の読み取りが発生します。エラーが発生します。
spring-cloud-context を導入すると、spring-boot-starter-actuator コンポーネントも導入され、これが開きます。一部のヘルス チェック ルートとポート。フレームワーク セキュリティに対する追加の制御が必要です
リソース ファイルの下のファイルを読み取るには、ClassPathResource を使用して 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 ファイルのコンテンツを取得した後、表示変更のためにそれをフロント デスクに視覚的に表示し、yaml.load を通じて変更されたコンテンツを Map 構造に変換します。メソッドを作成し、yaml.dumpAsMap を使用してストリームに変換し、ファイルに書き込みます。
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(); }
プログラムで yml プロパティを読み取って使用するには、通常 3 つの方法があります。
値のアノテーションを使用する
@Value("${system.systemName}") private String systemName;
環境インジェクションを読み込む
@Autowired private Environment environment; environment.getProperty("system.systemName")
ConfigurationProperties アノテーションを使用するRead
@Component @ConfigurationProperties(prefix = "system") public class SystemConfig { private String systemName; }
構成コレクション環境を介して読み取ります。getProperty メソッドは、実際には PropertySources に格納されます。すべてのキーと値のペアを取り出して、propertyMap に格納するだけです。更新された yml ファイルの内容を同じ形式の ymlMap に変換し、
しかし、yaml.load 後の ymlMap と PropertySources データ分解によって取り出された propertyMap は両方とも異なり、手動変換が必要です
propertyMap コレクションは単純なキーと値のペアであり、キーは system.systemName=>xxxxx などのプロパティ形式の名前です。 Group Management System
ymlMap コレクションはキー、ネストされた階層構造です。 LinkedHashMap の例、system=>(systemName=>xxxxx Group Management System)
変換方法は次のとおりです
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); } } }
更新方法は次のとおりです
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));
Value アノテーションであっても、ConfigurationProperties アノテーションであっても、実際には Bean オブジェクトのプロパティ メソッドを注入することで使用されます。最初にアノテーション RefreshValue をカスタマイズして、プロパティが設定されている Bean のクラスを変更します。が見つかります
InstantiationAwareBeanPostProcessorAdapter インターフェイスを実装すると、システムの起動時に対応する Bean がフィルタリングされて保存されます。yml ファイルを更新するときに、対応する
Bean のプロパティを Spring のイベントを通じて更新できます。 notification.
イベントを登録する EventListener アノテーションを使用します
@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); } } } }
トリガー イベントを通知し、ApplicationContext のpublishEvent メソッドを使用します
@Autowired private ApplicationContext applicationContext; for (String key : propertyMap.keySet()) { applicationContext.publishEvent(new YamlConfigRefreshPostProcessor.ConfigUpdateEvent(this, key)); }
YamlConfigRefreshPostProcessor の完全なコードは次のとおりです
リーリー以上がSpringBoot で yml ファイルを動的に更新する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。