In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
How to understand the ExtensionLoader.getActivateExtension of dubbo, in view of this problem, this article introduces the corresponding analysis and answer in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible way.
Mainly study the ExtensionLoader.getActivateExtension of dubbo
ExtensionLoader.getActivateExtension
Dubbo-2.7.3/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
Public class ExtensionLoader {private static final Logger logger = LoggerFactory.getLogger (ExtensionLoader.class); private static final String SERVICES_DIRECTORY = "META-INF/services/"; private static final String DUBBO_DIRECTORY = "META-INF/dubbo/"; private static final String DUBBO_INTERNAL_DIRECTORY = DUBBO_DIRECTORY + "internal/"; / /. / * This is equivalent to {@ code getActivateExtension (url, url.getParameter (key) .split (","), null)} * * @ param url url * @ param key url parameter key which used to get extension point names * @ param group group * @ return extension list which are activated. * @ see # getActivateExtension (org.apache.dubbo.common.URL, String [], String) * / public List getActivateExtension (URL url, String key, String group) {String value = url.getParameter (key); return getActivateExtension (url, StringUtils.isEmpty (value)? Null: COMMA_SPLIT_PATTERN.split (value), group);} / * * Get activate extensions. * * @ param url url * @ param values extension point names * @ param group group * @ return extension list which are activated * @ see org.apache.dubbo.common.extension.Activate * / public List getActivateExtension (URL url, String [] values, String group) {List exts = new ArrayList (); List names = values = = null? New ArrayList (0): Arrays.asList (values); if (! names.contains (REMOVE_VALUE_PREFIX + DEFAULT_KEY)) {getExtensionClasses (); for (Map.Entry 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 (activate instanceof com.alibaba.dubbo.common.extension.Activate) {activateGroup = ((com.alibaba.dubbo.common.extension.Activate) activate) .group () ActivateValue = ((com.alibaba.dubbo.common.extension.Activate) activate). Value ();} else {continue;} if (isMatchGroup (group, activateGroup)) {T ext = getExtension (name) If (! names.contains (name) & &! names.contains (REMOVE_VALUE_PREFIX + name) & & isActive (activateValue, url)) {exts.add (ext) } exts.sort (ActivateComparator.COMPARATOR);} List usrs = new ArrayList (); for (int I = 0; I
< names.size(); i++) { String name = names.get(i); if (!name.startsWith(REMOVE_VALUE_PREFIX) && !names.contains(REMOVE_VALUE_PREFIX + name)) { if (DEFAULT_KEY.equals(name)) { if (!usrs.isEmpty()) { exts.addAll(0, usrs); usrs.clear(); } } else { T ext = getExtension(name); usrs.add(ext); } } } if (!usrs.isEmpty()) { exts.addAll(usrs); } return exts; } private Map>Classes = cachedClasses.get (); if (classes = = null) {synchronized (cachedClasses) {classes = cachedClasses.get (); if (classes = = null) {classes = loadExtensionClasses (); cachedClasses.set (classes);} return classes } / / synchronized in getExtensionClasses private Map > extensionClasses = new HashMap (); loadDirectory (extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName ()); loadDirectory (extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName (). Replace ("org.apache", "com.alibaba")); loadDirectory (extensionClasses, DUBBO_DIRECTORY, type.getName ()); loadDirectory (extensionClasses, DUBBO_DIRECTORY, type.getName (). Replace ("org.apache", "com.alibaba")) LoadDirectory (extensionClasses, SERVICES_DIRECTORY, type.getName ()); loadDirectory (extensionClasses, SERVICES_DIRECTORY, type.getName (). Replace ("org.apache", "com.alibaba"); return extensionClasses } private void loadDirectory (Map > extensionClasses, ClassLoader classLoader, java.net.URL resourceURL) {try {try (BufferedReader reader = new BufferedReader (new InputStreamReader (resourceURL.openStream (), StandardCharsets.UTF_8) {String line; while ((line = reader.readLine ())! = null) {final int ci = line.indexOf ('#') If (ci > = 0) {line = line.substring (0, ci);} line = line.trim (); if (line.length () > 0) {try {String name = null Int I = line.indexOf ('='); if (I > 0) {name = line.substring (0, I) .trim (); line = line.substring (I + 1) .trim () } if (line.length () > 0) {loadClass (extensionClasses, resourceURL, Class.forName (line, true, classLoader), name) } catch (Throwable t) {IllegalStateException e = new IllegalStateException ("Failed to load extension class (interface:" + type + ", class line:" + line + ") in" + resourceURL + ", cause:" + t.getMessage (), t); exceptions.put (line, e) } catch (Throwable t) {logger.error ("Exception occurred when loading extension class (interface:" + type + ", class file:" + resourceURL + ") in" + resourceURL, t) }} private void loadClass (Map clazz, String name) throws NoSuchMethodException {if (! type.isAssignableFrom (clazz)) {throw new IllegalStateException ("Error occurred when loading extension class (interface:" + type + ", class line:" + clazz.getName () + "), class" + clazz.getName () + "is not subtype of interface.") } if (clazz.isAnnotationPresent (Adaptive.class)) {cacheAdaptiveClass (clazz);} else if (isWrapperClass (clazz)) {cacheWrapperClass (clazz);} else {clazz.getConstructor (); if (StringUtils.isEmpty (name)) {name = findAnnotationName (clazz) If (name.length () = 0) {throw new IllegalStateException ("No such extension name for the class" + clazz.getName () + "in the config" + resourceURL);}} String [] names = NAME_SEPARATOR.split (name); if (ArrayUtils.isNotEmpty (names)) {cacheActivateClass (clazz, names [0]) For (String n: names) {cacheName (clazz, n); saveInExtensionClass (extensionClasses, clazz, n);}} / * * cache Activate class which is annotated with Activate *
* for compatibility, also cache class with old alibaba Activate annotation * / private void cacheActivateClass (Class clazz, String name) {Activate activate = clazz.getAnnotation (Activate.class); if (activate! = null) {cachedActivates.put (name, activate) } else {/ / support com.alibaba.dubbo.common.extension.Activate com.alibaba.dubbo.common.extension.Activate oldActivate = clazz.getAnnotation (com.alibaba.dubbo.common.extension.Activate.class); if (oldActivate! = null) {cachedActivates.put (name, oldActivate) }} / * * Find the extension with the given name. If the specified name is not found, then {@ link IllegalStateException} * will be thrown. * / @ SuppressWarnings ("unchecked") public T getExtension (String name) {if (StringUtils.isEmpty (name)) {throw new IllegalArgumentException ("Extension name = = null");} if ("true" .equals (name)) {return getDefaultExtension ();} final Holder holder = getOrCreateHolder (name); Object instance = holder.get () If (instance = = null) {synchronized (holder) {instance = holder.get (); if (instance = = null) {instance = createExtension (name); holder.set (instance);} return (T) instance } / /.}
The getActivateExtension method first executes getExtensionClasses to load the extension class. Here, the loadDirectory method is used to load the extension in the META-INF/dubbo/, META-INF/dubbo/internal/, and META-INF/services/ directories.
The loadDirectory method calls the loadResource method, the loadResource method calls the loadClass method, and the loadClass method puts the Activate annotation information into the cachedActivates through cacheActivateClass
After traversing cachedActivates, the extension instance is put into exts through the getExtension method, and then sorted according to ActivateComparator.COMPARATOR. Finally, the extension of usr is loaded (so far, the code names seems to be empty all the time), and then the merge returns
ActivateComparator
Dubbotel CommonMutual 2.7.3 Mutual sources.jarAcheUniverse orgapacheGrexDUBBOGUBUBUR CommonUniverse extension supportUniverse ActivateComparative .java
Public class ActivateComparator implements Comparator {public static final Comparator COMPARATOR = new ActivateComparator (); @ Override public int compare (Object o1, Object O2) {if (o1 = = null & & O2 = = null) {return 0;} if (o1 = = null) {return-1;} if (O2 = = null) {return 1 } if (o1.equals (O2)) {return 0;} Class inf = findSpi (o1.getClass ()); ActivateInfo A1 = parseActivate (o1.getClass ()); ActivateInfo a2 = parseActivate (o2.getClass ()); if ((a1.applicableToCompare () | | a2.applicableToCompare ()) & inf! = null) {ExtensionLoader extensionLoader = ExtensionLoader.getExtensionLoader (inf) If (a1.applicableToCompare ()) {String N2 = extensionLoader.getExtensionName (o2.getClass ()); if (a1.isLess (N2)) {return-1;} if (a1.isMore (N2)) {return 1 }} if (a2.applicableToCompare ()) {String N1 = extensionLoader.getExtensionName (o1.getClass ()); if (a2.isLess (N1)) {return 1;} if (a2.isMore (N1)) {return-1 } int N1 = A1 = = null? 0: a1.order; int N2 = a2 = = null? 0: a2.order; / / never return 0 even if N1 equals N2, otherwise, o1 and O2 will override each other in collection like HashSet return N1 > N2:-1 } private Class findSpi (Class clazz) {if (clazz.getInterfaces (). Length clazz) {ActivateInfo info = new ActivateInfo (); if (clazz.isAnnotationPresent (Activate.class)) {Activate activate = clazz.getAnnotation (Activate.class); info.before = activate.before (); info.after = activate.after (); info.order = activate.order () } else {com.alibaba.dubbo.common.extension.Activate activate = clazz.getAnnotation (com.alibaba.dubbo.common.extension.Activate.class); info.before = activate.before (); info.after = activate.after (); info.order = activate.order ();} return info } private static class ActivateInfo {private String [] before; private String [] after; private int order; private boolean applicableToCompare () {return ArrayUtils.isNotEmpty (before) | | ArrayUtils.isNotEmpty (after);} private boolean isLess (String name) {return Arrays.asList (before) .requests (name) } private boolean isMore (String name) {return Arrays.asList (after) .resume (name);}
ActivateComparator first parses the annotation information to ActivateInfo through parseActivate, and then sorts the annotation information in ascending order according to its value for those with configured before or after. Otherwise, it is sorted by order (default is not specified as 0), which is greater than 1, otherwise-1 is returned.
Summary
The getActivateExtension method first executes getExtensionClasses to load the extension class. Here, the loadDirectory method is used to load the extension in the META-INF/dubbo/, META-INF/dubbo/internal/, and META-INF/services/ directories.
The loadDirectory method calls the loadResource method, the loadResource method calls the loadClass method, and the loadClass method puts the Activate annotation information into the cachedActivates through cacheActivateClass
After traversing cachedActivates, the extension instance is put into exts through the getExtension method, and then sorted according to ActivateComparator.COMPARATOR. Finally, the extension of usr is loaded (so far, the code names seems to be empty all the time), and then the merge returns
This is the answer to the ExtensionLoader.getActivateExtension question on how to understand dubbo. I hope the above content can be of some help to you. If you still have a lot of doubts to solve, you can follow the industry information channel to learn more about it.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.