From ef15ba9a7f78c8a9ae86c54738575705cbe38836 Mon Sep 17 00:00:00 2001 From: shedfreewu <49236872+shedfreewu@users.noreply.github.com> Date: Mon, 3 Mar 2025 12:56:23 +0800 Subject: [PATCH] fix: fix watch tsf config, fix bean refresh with RefreshScope and ConfigurationProperties. --- CHANGELOG.md | 1 + .../adapter/PolarisConfigFileLocator.java | 10 +++++----- .../spring/annotation/PolarisProcessor.java | 6 ++++++ .../annotation/SpringValueProcessor.java | 9 +++++++++ .../RefreshScopeSpringProcessorTest.java | 19 +++++++++++++++++++ 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e77b2985c0..8f96845611 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,3 +9,4 @@ - [feat:support default instance circuit breaker rule.](https://github.com/Tencent/spring-cloud-tencent/pull/1527) - [docs:update JDK version configuration in GitHub Actions.](https://github.com/Tencent/spring-cloud-tencent/pull/1528) - [fix: fix count circuit breaker in gateway & return 404 when context api does not match.](https://github.com/Tencent/spring-cloud-tencent/pull/1529) +- [fix:fix watch tsf config, fix bean refresh with RefreshScope and ConfigurationProperties.](https://github.com/Tencent/spring-cloud-tencent/pull/1530) diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java index 0a3f5d9e8f..89c651b48b 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java @@ -118,13 +118,13 @@ public static PolarisPropertySource loadGroupPolarisPropertySource(ConfigFileSer public static ConfigKVFile loadConfigKVFile(ConfigFileService configFileService, String namespace, String group, String fileName) { ConfigKVFile configKVFile; - // unknown extension is resolved as properties file - if (ConfigFileFormat.isPropertyFile(fileName) || ConfigFileFormat.isUnknownFile(fileName)) { - configKVFile = configFileService.getConfigPropertiesFile(namespace, group, fileName); - } - else if (ConfigFileFormat.isYamlFile(fileName)) { + // unknown extension is resolved as yaml file + if (ConfigFileFormat.isYamlFile(fileName) || ConfigFileFormat.isUnknownFile(fileName)) { configKVFile = configFileService.getConfigYamlFile(namespace, group, fileName); } + else if (ConfigFileFormat.isPropertyFile(fileName)) { + configKVFile = configFileService.getConfigPropertiesFile(namespace, group, fileName); + } else { LOGGER.warn("[SCT Config] Unsupported config file. namespace = {}, group = {}, fileName = {}", namespace, group, fileName); diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/annotation/PolarisProcessor.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/annotation/PolarisProcessor.java index 1ba9eb02df..4175909291 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/annotation/PolarisProcessor.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/annotation/PolarisProcessor.java @@ -58,6 +58,7 @@ public Object postProcessBeforeInitialization(Object bean, @NonNull String beanN catch (Exception ignored) { // ignore } + processClass(bean, beanName, clazz, isRefreshScope); for (Field field : findAllField(clazz)) { processField(bean, beanName, field, isRefreshScope); @@ -73,6 +74,11 @@ public Object postProcessAfterInitialization(@NonNull Object bean, @NonNull Stri return bean; } + /** + * subclass should implement this method to process class. + */ + protected abstract void processClass(Object bean, String beanName, Class clazz, boolean isRefreshScope); + /** * subclass should implement this method to process field. * @param bean bean diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/annotation/SpringValueProcessor.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/annotation/SpringValueProcessor.java index 7543a837d5..200ac9f736 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/annotation/SpringValueProcessor.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/annotation/SpringValueProcessor.java @@ -135,6 +135,15 @@ public Object postProcessBeforeInitialization(Object bean, @NonNull String beanN return bean; } + @Override + protected void processClass(Object bean, String beanName, Class clazz, boolean isRefreshScope) { + ConfigurationProperties configurationProperties = clazz.getAnnotation(ConfigurationProperties.class); + if (configurationProperties != null && isRefreshScope) { + // A bean with RefreshScope and ConfigurationProperties can't be refreshed by reflection, because it's proxied by Spring AOP. Related keys needs to be registered + parseConfigurationPropertiesKeys(configurationProperties, clazz); + } + } + @Override protected void processField(Object bean, String beanName, Field field, boolean isRefreshScope) { // register @Value on field diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/spring/annotation/RefreshScopeSpringProcessorTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/spring/annotation/RefreshScopeSpringProcessorTest.java index 11b17db592..d4ca75d4e0 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/spring/annotation/RefreshScopeSpringProcessorTest.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/spring/annotation/RefreshScopeSpringProcessorTest.java @@ -87,6 +87,7 @@ public void springValueFiledProcessorTest() { .withConfiguration(AutoConfigurations.of(TestConfig5.class)) .withConfiguration(AutoConfigurations.of(TestBeanProperties1.class)) .withConfiguration(AutoConfigurations.of(TestBeanProperties2.class)) + .withConfiguration(AutoConfigurations.of(TestBeanProperties3.class)) .withConfiguration(AutoConfigurations.of(PolarisConfigAutoConfiguration.class)) .withAllowBeanDefinitionOverriding(true) .withPropertyValues("spring.application.name=" + "conditionalOnConfigReflectEnabledTest") @@ -124,6 +125,9 @@ public void springValueFiledProcessorTest() { assertThat(springValueRegistry.isRefreshScopeKey("test.properties2.map.key")).isTrue(); assertThat(springValueRegistry.isRefreshScopeKey("test.properties2.notExist")).isFalse(); + // @RefreshScope and @ConfigurationProperties on @Component bean + assertThat(springValueRegistry.isRefreshScopeKey("test.properties3.name")).isTrue(); + assertThat(springValueRegistry.isRefreshScopeKey("test.properties3.notExist")).isFalse(); // @RefreshScope and @Bean on method, @Value bean in class assertThat(springValueRegistry.isRefreshScopeKey("test.bean5.name")).isTrue(); }); @@ -319,6 +323,21 @@ public void setInner(InnerProperties inner) { } } + @Component + @RefreshScope + @ConfigurationProperties(prefix = "test.properties3") + static class TestBeanProperties3 { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + static class InnerProperties { private String name;