dubbo SPI mechanism

Source analysis:

/ ** 
     * Get the extension class 
     * / 
    @SuppressWarnings ( "an unchecked" )
     public T GetExtension (String name) {
         IF (StringUtils.isEmpty (name)) {
             the throw  new new an IllegalArgumentException ( "the Extension name == null" ); 
        } 
        // Gets the default implementation class expansion 
        IF ( "to true" .equals (name)) {
             return getDefaultExtension (); 
        } 
        // holder for holding a target object 
        Final holder <Object> = holder getOrCreateHolder (name); 
        Object instance = holder. GET ();
         //Double check 
        IF (instance == null ) {
             the synchronized (holder) { 
                instance = holder.get ();
                 IF (instance == null ) {
                     // create expanding instance 
                    instance = createExtension (name);
                     // set the instance to the holder 
                    holder.set (instance); 
                } 
            } 
        } 
        return (T) instance; 
    }
// 创建拓展对象
    @SuppressWarnings("unchecked")
    private T createExtension(String name) {
        Class<?> clazz = getExtensionClasses().get(name);
        if (clazz == null) {
            throw findException(name);
        }
        try {
            T instance = (T) EXTENSION_INSTANCES.get(clazz);
            if (instance == null) {
                // 通过反射创建实例
                EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
                instance =(T) EXTENSION_INSTANCES.get (clazz); 
            } 
            // injected into the instance dependent 
            injectExtension (instance); 
            the Set <Class <>> wrapperClasses =? CachedWrapperClasses;
             IF (CollectionUtils.isNotEmpty (wrapperClasses)) {
                 // cycle created instance Wrapper 
                for (Class <?> wrapperClass: wrapperClasses) {
                     // the current instance as a parameter to the constructor Wrapper, and creates Wrapper instance by reflection.
                    // then injected into Wrapper dependency example last instance reassigned to the Wrapper instance variable 
                    instance = injectExtension ((T) wrapperClass.getConstructor (type) .newInstance (instance)); 
                } 
            } 
            return instance;
        } catch (Throwable t) {
            throw new IllegalStateException("Extension instance (name: " + name + ", class: " + type
                    + ") couldn't be instantiated: " + t.getMessage(), t);
        }
    }
// loaded from the configuration file expand all classes available "configuration item name" to "configuration classes" mapping table 
    Private the Map <String, Class <? >> getExtensionClasses () {
         // get from the cache is loaded the expansion of the class 
        the Map <String, class <= >> classes? cachedClasses.get ();
         // double check 
        IF (classes == null ) {
             the synchronized (cachedClasses) { 
                classes = cachedClasses.get ();
                 IF (classes == null ) {
                     // load class expand 
                    classes = loadExtensionClasses (); 
                    cachedClasses.set (classes);
                }
            }
        }
        return classes;
    }

 

    // synchronized in getExtensionClasses
    private Map<String, Class<?>> loadExtensionClasses() {
        cacheDefaultExtensionName();

        Map<String, Class<?>> 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 (the Map <String, Class <>>? extensionClasses, dir String, String of the type) {
         // fileName = folder path + type the fully qualified name 
        String fileName = dir + of the type;
         the try { 
            Enumeration <java.net.URL > URLs; 
            ClassLoader classLoader = findClassLoader ();
             // load all the file name of the same file 
            IF (classLoader =! null ) { 
                URLs = ClassLoader.getResources (fileName); 
            } the else { 
                URLs = ClassLoader.getSystemResources(fileName);
            }
            if (urls != null) {
                while (urls.hasMoreElements()) {
                    java.net.URL resourceURL = urls.nextElement();
                    // 加载资源
                    loadResource(extensionClasses, classLoader, resourceURL);
                }
            }
        } catch (Throwable t) {
            logger.error("Exception occurred when loading extension class (interface: " + type + ", description file: "
                    + fileName + ").", t);
        }
    }

 

Guess you like

Origin www.cnblogs.com/wongandy/p/11541642.html