diff --git a/CHANGELOG.md b/CHANGELOG.md index a1c8d8a8f..40427df17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,4 +20,5 @@ - [feat: support 2.0.0 config](https://github.com/Tencent/spring-cloud-tencent/pull/1463) - [feat:upgrade trace plugin.](https://github.com/Tencent/spring-cloud-tencent/pull/1467) - [feat:upgrade 2.0.0 service.](https://github.com/Tencent/spring-cloud-tencent/pull/1471) -- [fix:fix zuul delay circuit breaker.](https://github.com/Tencent/spring-cloud-tencent/pull/1519) \ No newline at end of file +- [fix:fix zuul delay circuit breaker.](https://github.com/Tencent/spring-cloud-tencent/pull/1519) +- [fix:fix watch tsf config, fix bean refresh with RefreshScope and ConfigurationProperties.](https://github.com/Tencent/spring-cloud-tencent/pull/1520) \ No newline at end of file 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 9e4ca27cf..8b3f96b96 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 @@ -315,13 +315,13 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { 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 1ba9eb02d..417590929 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 abstract class PolarisProcessor implements BeanPostProcessor, PriorityOrd catch (Exception ignored) { // ignore } + processClass(bean, beanName, clazz, isRefreshScope); for (Field field : findAllField(clazz)) { processField(bean, beanName, field, isRefreshScope); @@ -73,6 +74,11 @@ public abstract class PolarisProcessor implements BeanPostProcessor, PriorityOrd 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 d925d7cfe..19e4a0f56 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 @@ -109,6 +109,15 @@ public class SpringValueProcessor extends PolarisProcessor implements BeanDefini } + @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 11b17db59..d4ca75d4e 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 class RefreshScopeSpringProcessorTest { .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 class RefreshScopeSpringProcessorTest { 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 class RefreshScopeSpringProcessorTest { } } + @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;