Support refresh specific ConfigurationPropertiesBean

pull/2609/head
Freeman Lau 3 years ago
parent 2b6837b8cf
commit 9d45b28d52

@ -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)

@ -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,
}

@ -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<String> 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);
}
}));

@ -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."
}
]

@ -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();
}
}
}

@ -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<String> 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

Loading…
Cancel
Save