From 9d45b28d528b11c31c059a5b4c08c372d14033b9 Mon Sep 17 00:00:00 2001 From: Freeman Lau Date: Sun, 6 Mar 2022 17:22:10 +0800 Subject: [PATCH] Support refresh specific ConfigurationPropertiesBean --- .../NacosConfigBootstrapConfiguration.java | 2 +- .../cloud/nacos/refresh/RefreshBehavior.java | 10 ++- .../SmartConfigurationPropertiesRebinder.java | 13 +-- ...itional-spring-configuration-metadata.json | 2 +- .../NacosConfigAutoConfigurationTest.java | 82 +++++++++++++++++++ ...tionPropertiesRebinderIntegrationTest.java | 29 ++----- 6 files changed, 104 insertions(+), 34 deletions(-) create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigAutoConfigurationTest.java diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigBootstrapConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigBootstrapConfiguration.java index bc70499e6..6abd1ac8f 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigBootstrapConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigBootstrapConfiguration.java @@ -56,7 +56,7 @@ public class NacosConfigBootstrapConfiguration { /** - * Compatible with spring boot < 2.4.0. + * Compatible with bootstrap way to start. */ @Bean @ConditionalOnMissingBean(search = SearchStrategy.CURRENT) diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/refresh/RefreshBehavior.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/refresh/RefreshBehavior.java index 904b0e541..9cf27101e 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/refresh/RefreshBehavior.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/refresh/RefreshBehavior.java @@ -16,6 +16,8 @@ package com.alibaba.cloud.nacos.refresh; +import org.springframework.boot.context.properties.ConfigurationPropertiesBean; + /** * Refresh behavior. * @@ -23,11 +25,11 @@ package com.alibaba.cloud.nacos.refresh; */ public enum RefreshBehavior { /** - * Refresh all ConfigurationPropertiesBean. + * Refresh all {@link ConfigurationPropertiesBean}s. */ - ALL, + ALL_BEANS, /** - * Refresh specific ConfigurationPropertiesBean base on change key. + * Refresh specific {@link ConfigurationPropertiesBean} base on change key. */ - SPECIFIC + SPECIFIC_BEAN, } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/refresh/SmartConfigurationPropertiesRebinder.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/refresh/SmartConfigurationPropertiesRebinder.java index de9a5fa24..3ab59f359 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/refresh/SmartConfigurationPropertiesRebinder.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/refresh/SmartConfigurationPropertiesRebinder.java @@ -80,7 +80,7 @@ public class SmartConfigurationPropertiesRebinder this.applicationContext = applicationContext; this.refreshBehavior = this.applicationContext.getEnvironment().getProperty( "spring.cloud.nacos.config.refresh-behavior", RefreshBehavior.class, - RefreshBehavior.ALL); + RefreshBehavior.ALL_BEANS); } @Override @@ -89,21 +89,22 @@ public class SmartConfigurationPropertiesRebinder // Backwards compatible || event.getKeys().equals(event.getSource())) { switch (refreshBehavior) { - case SPECIFIC: - rebindSpecific(event); + case SPECIFIC_BEAN: + rebindSpecificBean(event); break; default: rebind(); + break; } } } - private void rebindSpecific(EnvironmentChangeEvent event) { + private void rebindSpecificBean(EnvironmentChangeEvent event) { Set refreshedSet = new HashSet<>(); - beanMap.forEach((name, bean) -> event.getKeys().forEach(key -> { + beanMap.forEach((name, bean) -> event.getKeys().forEach(changeKey -> { String prefix = AnnotationUtils.getValue(bean.getAnnotation()).toString(); // prevent multiple refresh one ConfigurationPropertiesBean. - if (key.startsWith(prefix) && refreshedSet.add(name)) { + if (changeKey.startsWith(prefix) && refreshedSet.add(name)) { rebind(name); } })); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/resources/META-INF/additional-spring-configuration-metadata.json index e4a413258..0bd155074 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -92,7 +92,7 @@ { "name": "spring.cloud.nacos.config.refresh-behavior", "type": "com.alibaba.cloud.nacos.refresh.RefreshBehavior", - "defaultValue": "ALL", + "defaultValue": "all_beans", "description": "ConfigurationPropertiesBean refresh behavior." } ] diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigAutoConfigurationTest.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigAutoConfigurationTest.java new file mode 100644 index 000000000..893919d6a --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigAutoConfigurationTest.java @@ -0,0 +1,82 @@ +/* + * Copyright 2013-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.cloud.nacos; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.cloud.context.properties.ConfigurationPropertiesBeans; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * NacosConfigAutoConfiguration Tester. + * + * @author freeman + */ +public class NacosConfigAutoConfigurationTest { + + AnnotationConfigApplicationContext context; + + @BeforeEach + public void reset() { + // compatible with legacy tests + System.setProperty("spring.cloud.bootstrap.enabled", "true"); + context = new AnnotationConfigApplicationContext( + NacosConfigAutoConfiguration.class, Config.class); + } + + @Test + public void noImports_thenCreateProperties() { + assertThat(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, + NacosConfigProperties.class).length).isEqualTo(1); + assertThat(context.getBean(NacosConfigProperties.class).getServerAddr()) + .isEqualTo("127.0.0.1:8848"); + context.close(); + } + + @Test + public void imports_thenNoCreateProperties() { + // mock import + context.registerBean(NacosConfigProperties.class, () -> { + NacosConfigProperties properties = new NacosConfigProperties(); + properties.setServerAddr("localhost"); + return properties; + }); + + assertThat(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, + NacosConfigProperties.class).length).isEqualTo(1); + assertThat(context.getBean(NacosConfigProperties.class).getServerAddr()) + .isEqualTo("localhost"); + context.close(); + } + + @Configuration + static class Config { + + @Bean + public ConfigurationPropertiesBeans beans() { + return new ConfigurationPropertiesBeans(); + } + + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/SmartConfigurationPropertiesRebinderIntegrationTest.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/SmartConfigurationPropertiesRebinderIntegrationTest.java index 325082ce6..9829e4277 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/SmartConfigurationPropertiesRebinderIntegrationTest.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/SmartConfigurationPropertiesRebinderIntegrationTest.java @@ -16,9 +16,6 @@ package com.alibaba.cloud.nacos; -import java.util.HashSet; -import java.util.Set; - import com.alibaba.cloud.nacos.refresh.RefreshBehavior; import com.alibaba.cloud.nacos.refresh.SmartConfigurationPropertiesRebinder; import org.junit.jupiter.api.Test; @@ -27,15 +24,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.test.util.ReflectionTestUtils; import static com.alibaba.cloud.nacos.SmartConfigurationPropertiesRebinderIntegrationTest.TestConfig; import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; /** * @@ -43,15 +38,15 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author freeman * @date 2022/2/6 */ -@SpringBootTest(classes = TestConfig.class, properties = { - "spring.cloud.nacos.config.refresh-behavior=specific", - "spring.cloud.nacos.server-addr=123.123.123.123:8848" }, webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = TestConfig.class, webEnvironment = NONE, properties = { + "spring.cloud.nacos.config.refresh-behavior=specific_bean", + "spring.cloud.nacos.server-addr=123.123.123.123:8848", + "spring.cloud.nacos.config.import-check.enabled=false" +}) public class SmartConfigurationPropertiesRebinderIntegrationTest { @Autowired private ConfigurationPropertiesRebinder rebinder; - @Autowired - private ApplicationContext context; @Test public void testUsingSmartConfigurationPropertiesRebinder() { @@ -60,17 +55,7 @@ public class SmartConfigurationPropertiesRebinderIntegrationTest { RefreshBehavior refreshBehavior = (RefreshBehavior) ReflectionTestUtils .getField(rebinder, "refreshBehavior"); - assertThat(refreshBehavior).isEqualTo(RefreshBehavior.SPECIFIC); - } - - @Test - public void testSpecificRefreshWork() { - Set keys = new HashSet<>(); - keys.add("spring.cloud.nacos.config.server-addr"); - keys.add("spring.cloud.nacos.config.name"); - - // for debug - context.publishEvent(new EnvironmentChangeEvent(context, keys)); + assertThat(refreshBehavior).isEqualTo(RefreshBehavior.SPECIFIC_BEAN); } @Configuration