|
@@ -1,18 +1,5 @@
|
|
package com.ctrip.framework.apollo.internals;
|
|
package com.ctrip.framework.apollo.internals;
|
|
|
|
|
|
-import java.util.Date;
|
|
|
|
-import java.util.List;
|
|
|
|
-import java.util.Locale;
|
|
|
|
-import java.util.Map;
|
|
|
|
-import java.util.Properties;
|
|
|
|
-import java.util.Set;
|
|
|
|
-import java.util.concurrent.ExecutorService;
|
|
|
|
-import java.util.concurrent.Executors;
|
|
|
|
-import java.util.concurrent.atomic.AtomicLong;
|
|
|
|
-
|
|
|
|
-import org.slf4j.Logger;
|
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
|
-
|
|
|
|
import com.ctrip.framework.apollo.Config;
|
|
import com.ctrip.framework.apollo.Config;
|
|
import com.ctrip.framework.apollo.ConfigChangeListener;
|
|
import com.ctrip.framework.apollo.ConfigChangeListener;
|
|
import com.ctrip.framework.apollo.build.ApolloInjector;
|
|
import com.ctrip.framework.apollo.build.ApolloInjector;
|
|
@@ -33,6 +20,18 @@ import com.google.common.cache.CacheBuilder;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Maps;
|
|
import com.google.common.collect.Maps;
|
|
import com.google.common.collect.Sets;
|
|
import com.google.common.collect.Sets;
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
+
|
|
|
|
+import java.util.Date;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Locale;
|
|
|
|
+import java.util.Map;
|
|
|
|
+import java.util.Properties;
|
|
|
|
+import java.util.Set;
|
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
|
+import java.util.concurrent.Executors;
|
|
|
|
+import java.util.concurrent.atomic.AtomicLong;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @author Jason Song(song_s@ctrip.com)
|
|
* @author Jason Song(song_s@ctrip.com)
|
|
@@ -44,6 +43,7 @@ public abstract class AbstractConfig implements Config {
|
|
|
|
|
|
private final List<ConfigChangeListener> m_listeners = Lists.newCopyOnWriteArrayList();
|
|
private final List<ConfigChangeListener> m_listeners = Lists.newCopyOnWriteArrayList();
|
|
private final Map<ConfigChangeListener, Set<String>> m_interestedKeys = Maps.newConcurrentMap();
|
|
private final Map<ConfigChangeListener, Set<String>> m_interestedKeys = Maps.newConcurrentMap();
|
|
|
|
+ private final Map<ConfigChangeListener, Set<String>> m_interestedKeyPrefixes = Maps.newConcurrentMap();
|
|
private final ConfigUtil m_configUtil;
|
|
private final ConfigUtil m_configUtil;
|
|
private volatile Cache<String, Integer> m_integerCache;
|
|
private volatile Cache<String, Integer> m_integerCache;
|
|
private volatile Cache<String, Long> m_longCache;
|
|
private volatile Cache<String, Long> m_longCache;
|
|
@@ -77,17 +77,26 @@ public abstract class AbstractConfig implements Config {
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public void addChangeListener(ConfigChangeListener listener, Set<String> interestedKeys) {
|
|
public void addChangeListener(ConfigChangeListener listener, Set<String> interestedKeys) {
|
|
|
|
+ addChangeListener(listener, interestedKeys, null);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void addChangeListener(ConfigChangeListener listener, Set<String> interestedKeys, Set<String> interestedKeyPrefixes) {
|
|
if (!m_listeners.contains(listener)) {
|
|
if (!m_listeners.contains(listener)) {
|
|
m_listeners.add(listener);
|
|
m_listeners.add(listener);
|
|
if (interestedKeys != null && !interestedKeys.isEmpty()) {
|
|
if (interestedKeys != null && !interestedKeys.isEmpty()) {
|
|
m_interestedKeys.put(listener, Sets.newHashSet(interestedKeys));
|
|
m_interestedKeys.put(listener, Sets.newHashSet(interestedKeys));
|
|
}
|
|
}
|
|
|
|
+ if (interestedKeyPrefixes != null && !interestedKeyPrefixes.isEmpty()) {
|
|
|
|
+ m_interestedKeyPrefixes.put(listener, Sets.newHashSet(interestedKeyPrefixes));
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public boolean removeChangeListener(ConfigChangeListener listener) {
|
|
public boolean removeChangeListener(ConfigChangeListener listener) {
|
|
m_interestedKeys.remove(listener);
|
|
m_interestedKeys.remove(listener);
|
|
|
|
+ m_interestedKeyPrefixes.remove(listener);
|
|
return m_listeners.remove(listener);
|
|
return m_listeners.remove(listener);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -453,14 +462,28 @@ public abstract class AbstractConfig implements Config {
|
|
|
|
|
|
private boolean isConfigChangeListenerInterested(ConfigChangeListener configChangeListener, ConfigChangeEvent configChangeEvent) {
|
|
private boolean isConfigChangeListenerInterested(ConfigChangeListener configChangeListener, ConfigChangeEvent configChangeEvent) {
|
|
Set<String> interestedKeys = m_interestedKeys.get(configChangeListener);
|
|
Set<String> interestedKeys = m_interestedKeys.get(configChangeListener);
|
|
|
|
+ Set<String> interestedKeyPrefixes = m_interestedKeyPrefixes.get(configChangeListener);
|
|
|
|
|
|
- if (interestedKeys == null || interestedKeys.isEmpty()) {
|
|
|
|
|
|
+ if ((interestedKeys == null || interestedKeys.isEmpty())
|
|
|
|
+ && (interestedKeyPrefixes == null || interestedKeyPrefixes.isEmpty())) {
|
|
return true; // no interested keys means interested in all keys
|
|
return true; // no interested keys means interested in all keys
|
|
}
|
|
}
|
|
|
|
|
|
- for (String interestedKey : interestedKeys) {
|
|
|
|
- if (configChangeEvent.isChanged(interestedKey)) {
|
|
|
|
- return true;
|
|
|
|
|
|
+ if (interestedKeys != null) {
|
|
|
|
+ for (String interestedKey : interestedKeys) {
|
|
|
|
+ if (configChangeEvent.isChanged(interestedKey)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (interestedKeyPrefixes != null) {
|
|
|
|
+ for (String prefix : interestedKeyPrefixes) {
|
|
|
|
+ for (final String changedKey : configChangeEvent.changedKeys()) {
|
|
|
|
+ if (changedKey.startsWith(prefix)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|