diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/AutoUpdateConfigChangeListener.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/AutoUpdateConfigChangeListener.java index 830151e846b8a118dc63f81d7ead91d7bf01ed08..eeb83c6e227c873c02f4d181b51e0cca0fe4fe5d 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/AutoUpdateConfigChangeListener.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/AutoUpdateConfigChangeListener.java @@ -2,6 +2,7 @@ package com.ctrip.framework.apollo.spring.property; import com.ctrip.framework.apollo.ConfigChangeListener; import com.ctrip.framework.apollo.build.ApolloInjector; +import com.ctrip.framework.apollo.enums.PropertyChangeType; import com.ctrip.framework.apollo.model.ConfigChange; import com.ctrip.framework.apollo.model.ConfigChangeEvent; import com.ctrip.framework.apollo.spring.annotation.SpringValueProcessor; @@ -57,8 +58,7 @@ public class AutoUpdateConfigChangeListener implements ConfigChangeListener{ } // 2. check whether the value is really changed or not (since spring property sources have hierarchies) - ConfigChange configChange = changeEvent.getChange(key); - if (!Objects.equals(environment.getProperty(key), configChange.getNewValue())) { + if (!shouldTriggerAutoUpdate(changeEvent, key)) { continue; } @@ -69,6 +69,23 @@ public class AutoUpdateConfigChangeListener implements ConfigChangeListener{ } } + /** + * Check whether we should trigger the auto update or not. + *
+ * For added or modified keys, we should trigger auto update if the current value in Spring equals to the new value. + *
+ * For deleted keys, we will trigger auto update anyway. + */ + private boolean shouldTriggerAutoUpdate(ConfigChangeEvent changeEvent, String changedKey) { + ConfigChange configChange = changeEvent.getChange(changedKey); + + if (configChange.getChangeType() == PropertyChangeType.DELETED) { + return true; + } + + return Objects.equals(environment.getProperty(changedKey), configChange.getNewValue()); + } + private void updateSpringValue(SpringValue springValue) { try { Object value = resolvePropertyValue(springValue); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java index d799559b3e1022de08584ab1b83e18d92f697dbe..f0b898d2cd616e068a9d843f5c71314ce26f0cad 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java @@ -301,6 +301,36 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati assertEquals(DEFAULT_BATCH, bean.getBatch()); } + @Test + public void testAutoUpdateWithMultipleNamespacesWithSamePropertiesDeleted() throws Exception { + int someTimeout = 1000; + int someBatch = 2000; + int anotherBatch = 3000; + + Properties applicationProperties = assembleProperties(BATCH_PROPERTY, String.valueOf(someBatch)); + Properties fxApolloProperties = + assembleProperties(TIMEOUT_PROPERTY, String.valueOf(someTimeout), BATCH_PROPERTY, String.valueOf(anotherBatch)); + + SimpleConfig applicationConfig = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); + SimpleConfig fxApolloConfig = prepareConfig(FX_APOLLO_NAMESPACE, fxApolloProperties); + + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig2.class); + + TestJavaConfigBean bean = context.getBean(TestJavaConfigBean.class); + + assertEquals(someTimeout, bean.getTimeout()); + assertEquals(someBatch, bean.getBatch()); + + Properties newProperties = new Properties(); + + applicationConfig.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + + TimeUnit.MILLISECONDS.sleep(50); + + assertEquals(someTimeout, bean.getTimeout()); + assertEquals(anotherBatch, bean.getBatch()); + } + @Test public void testAutoUpdateWithDeletedPropertiesWithNoDefaultValue() throws Exception { int initialTimeout = 1000; diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderAutoUpdateTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderAutoUpdateTest.java index 161be3e592d3696df40c6a9e9828b6d21b462710..436130f78a23dae8b7726f1b74d6c429e775ad3b 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderAutoUpdateTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderAutoUpdateTest.java @@ -262,6 +262,38 @@ public class XmlConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegratio assertEquals(DEFAULT_BATCH, bean.getBatch()); } + @Test + public void testAutoUpdateWithMultipleNamespacesWithSamePropertiesDeleted() throws Exception { + int someTimeout = 1000; + int someBatch = 2000; + int anotherBatch = 3000; + + Properties applicationProperties = assembleProperties(BATCH_PROPERTY, + String.valueOf(someBatch)); + Properties fxApolloProperties = assembleProperties(TIMEOUT_PROPERTY, + String.valueOf(someTimeout), BATCH_PROPERTY, String.valueOf(anotherBatch)); + + SimpleConfig applicationConfig = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, + applicationProperties); + SimpleConfig fxApolloConfig = prepareConfig(FX_APOLLO_NAMESPACE, fxApolloProperties); + + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest3.xml"); + + TestXmlBean bean = context.getBean(TestXmlBean.class); + + assertEquals(someTimeout, bean.getTimeout()); + assertEquals(someBatch, bean.getBatch()); + + Properties newProperties = new Properties(); + + applicationConfig.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + + TimeUnit.MILLISECONDS.sleep(50); + + assertEquals(someTimeout, bean.getTimeout()); + assertEquals(anotherBatch, bean.getBatch()); + } + @Test public void testAutoUpdateWithDeletedPropertiesWithNoDefaultValue() throws Exception { int initialTimeout = 1000;