diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/Config.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/Config.java index d80cf8b722d964e561fef190cd97235b030e9e0d..1ad6a68d9d4e6969f219304d9c1c7d02c9bebb7c 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/Config.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/Config.java @@ -178,6 +178,14 @@ public interface Config { */ public void addChangeListener(ConfigChangeListener listener, Set interestedKeys); + /** + * Remove the change listener + * + * @param listener the specific config change listener to remove + * @return true if the specific config change listener is found and removed + */ + public boolean removeChangeListener(ConfigChangeListener listener); + /** * Return a set of the property names * diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfig.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfig.java index 8bfd61720b54b14f5e97802ddd5a2e3f325c53f2..2bc0dd18f101c051146291f509d30277368151a0 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfig.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfig.java @@ -85,6 +85,12 @@ public abstract class AbstractConfig implements Config { } } + @Override + public boolean removeChangeListener(ConfigChangeListener listener) { + m_interestedKeys.remove(listener); + return m_listeners.remove(listener); + } + @Override public Integer getIntProperty(String key, Integer defaultValue) { try { diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigTest.java index fd3b77930f7c796d7247fef7eb563278a526a359..43f9fca23632db0fd4724dabfd79ebe5f2834dd6 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigTest.java @@ -3,6 +3,7 @@ package com.ctrip.framework.apollo.internals; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -705,6 +706,62 @@ public class DefaultConfigTest { assertFalse(interestedInSomeKeyNotChangedFuture.isDone()); } + @Test + public void testRemoveChangeListener() throws Exception { + String someNamespace = "someNamespace"; + final ConfigChangeEvent someConfigChangEvent = mock(ConfigChangeEvent.class); + ConfigChangeEvent anotherConfigChangEvent = mock(ConfigChangeEvent.class); + + final SettableFuture someListenerFuture1 = SettableFuture.create(); + final SettableFuture someListenerFuture2 = SettableFuture.create(); + ConfigChangeListener someListener = new ConfigChangeListener() { + @Override + public void onChange(ConfigChangeEvent changeEvent) { + if (someConfigChangEvent == changeEvent) { + someListenerFuture1.set(changeEvent); + } else { + someListenerFuture2.set(changeEvent); + } + } + }; + + final SettableFuture anotherListenerFuture1 = SettableFuture.create(); + final SettableFuture anotherListenerFuture2 = SettableFuture.create(); + ConfigChangeListener anotherListener = new ConfigChangeListener() { + @Override + public void onChange(ConfigChangeEvent changeEvent) { + if (someConfigChangEvent == changeEvent) { + anotherListenerFuture1.set(changeEvent); + } else { + anotherListenerFuture2.set(changeEvent); + } + } + }; + + ConfigChangeListener yetAnotherListener = mock(ConfigChangeListener.class); + + DefaultConfig config = new DefaultConfig(someNamespace, mock(ConfigRepository.class)); + + config.addChangeListener(someListener); + config.addChangeListener(anotherListener); + + config.fireConfigChange(someConfigChangEvent); + + assertEquals(someConfigChangEvent, someListenerFuture1.get(500, TimeUnit.MILLISECONDS)); + assertEquals(someConfigChangEvent, anotherListenerFuture1.get(500, TimeUnit.MILLISECONDS)); + + assertFalse(config.removeChangeListener(yetAnotherListener)); + assertTrue(config.removeChangeListener(someListener)); + + config.fireConfigChange(anotherConfigChangEvent); + + assertEquals(anotherConfigChangEvent, anotherListenerFuture2.get(500, TimeUnit.MILLISECONDS)); + + TimeUnit.MILLISECONDS.sleep(100); + + assertFalse(someListenerFuture2.isDone()); + } + @Test public void testGetPropertyNames() { String someKeyPrefix = "someKey";