in dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java [343:438]
public List<T> getActivateExtension(URL url, String[] values, String group) {
checkDestroyed();
// solve the bug of using @SPI's wrapper method to report a null pointer exception.
Map<Class<?>, T> activateExtensionsMap = new TreeMap<>(activateComparator);
List<String> names = values == null
? new ArrayList<>(0)
: Arrays.stream(values).map(StringUtils::trim).collect(Collectors.toList());
Set<String> namesSet = new HashSet<>(names);
if (!namesSet.contains(REMOVE_VALUE_PREFIX + DEFAULT_KEY)) {
if (cachedActivateGroups.size() == 0) {
synchronized (cachedActivateGroups) {
// cache all extensions
if (cachedActivateGroups.size() == 0) {
getExtensionClasses();
for (Map.Entry<String, Object> entry : cachedActivates.entrySet()) {
String name = entry.getKey();
Object activate = entry.getValue();
String[] activateGroup, activateValue;
if (activate instanceof Activate) {
activateGroup = ((Activate) activate).group();
activateValue = ((Activate) activate).value();
} else if (Dubbo2CompactUtils.isEnabled()
&& Dubbo2ActivateUtils.isActivateLoaded()
&& Dubbo2ActivateUtils.getActivateClass().isAssignableFrom(activate.getClass())) {
activateGroup = Dubbo2ActivateUtils.getGroup((Annotation) activate);
activateValue = Dubbo2ActivateUtils.getValue((Annotation) activate);
} else {
continue;
}
cachedActivateGroups.put(name, new HashSet<>(Arrays.asList(activateGroup)));
String[][] keyPairs = new String[activateValue.length][];
for (int i = 0; i < activateValue.length; i++) {
if (activateValue[i].contains(":")) {
keyPairs[i] = new String[2];
String[] arr = activateValue[i].split(":");
keyPairs[i][0] = arr[0];
keyPairs[i][1] = arr[1];
} else {
keyPairs[i] = new String[1];
keyPairs[i][0] = activateValue[i];
}
}
cachedActivateValues.put(name, keyPairs);
}
}
}
}
// traverse all cached extensions
cachedActivateGroups.forEach((name, activateGroup) -> {
if (isMatchGroup(group, activateGroup)
&& !namesSet.contains(name)
&& !namesSet.contains(REMOVE_VALUE_PREFIX + name)
&& isActive(cachedActivateValues.get(name), url)) {
activateExtensionsMap.put(getExtensionClass(name), getExtension(name));
}
});
}
if (namesSet.contains(DEFAULT_KEY)) {
// will affect order
// `ext1,default,ext2` means ext1 will happens before all of the default extensions while ext2 will after
// them
ArrayList<T> extensionsResult = new ArrayList<>(activateExtensionsMap.size() + names.size());
for (String name : names) {
if (name.startsWith(REMOVE_VALUE_PREFIX) || namesSet.contains(REMOVE_VALUE_PREFIX + name)) {
continue;
}
if (DEFAULT_KEY.equals(name)) {
extensionsResult.addAll(activateExtensionsMap.values());
continue;
}
if (containsExtension(name)) {
extensionsResult.add(getExtension(name));
}
}
return extensionsResult;
} else {
// add extensions, will be sorted by its order
for (String name : names) {
if (name.startsWith(REMOVE_VALUE_PREFIX) || namesSet.contains(REMOVE_VALUE_PREFIX + name)) {
continue;
}
if (DEFAULT_KEY.equals(name)) {
continue;
}
if (containsExtension(name)) {
activateExtensionsMap.put(getExtensionClass(name), getExtension(name));
}
}
return new ArrayList<>(activateExtensionsMap.values());
}
}