You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by hu...@apache.org on 2019/02/22 14:54:08 UTC

[incubator-dubbo-website] branch asf-site updated: Fix some typos for [introduction-to-dubbo-spi-2.md] (#301)

This is an automated email from the ASF dual-hosted git repository.

huxing pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo-website.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new 39102aa  Fix some typos for [introduction-to-dubbo-spi-2.md] (#301)
39102aa is described below

commit 39102aa64cf6eb8fbc753aba9392e8b530e7d3ff
Author: web <er...@qq.com>
AuthorDate: Fri Feb 22 22:54:03 2019 +0800

    Fix some typos for [introduction-to-dubbo-spi-2.md] (#301)
---
 blog/en-us/introduction-to-dubbo-spi-2.md | 85 +++++++++++++++---------------
 blog/zh-cn/introduction-to-dubbo-spi-2.md | 86 ++++++++++++++++---------------
 2 files changed, 87 insertions(+), 84 deletions(-)

diff --git a/blog/en-us/introduction-to-dubbo-spi-2.md b/blog/en-us/introduction-to-dubbo-spi-2.md
index 9d7946c..7c9048f 100644
--- a/blog/en-us/introduction-to-dubbo-spi-2.md
+++ b/blog/en-us/introduction-to-dubbo-spi-2.md
@@ -5,13 +5,12 @@ description: This article introduces the principles and details of Dubbo's SPI.
 ---
 
 # Dubbo extensible mechanism source code analysis
----
 
 In the [actual implementation of the Dubbo extensibility mechanism](./introduction-to-dubbo-spi.md), we learned some concepts of the Dubbo extension mechanism, explored the implementation of LoadBalance in Dubbo, and implemented a LoadBalance on our own. Do you think Dubbo's extension mechanism is great? Next, we will go deep into the source code of Dubbo and see what it is.
 
 ## ExtensionLoader
 
-`ExtentionLoader` is the core class, which is responsible for the loading and lifecycle management of extension points. Let's start with this class. There are many methods of Extension, and the common methods include:
+`ExtensionLoader` is the core class, which is responsible for the loading and lifecycle management of extension points. Let's start with this class. There are many methods of Extension, and the common methods include:
 
 * `public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type)`
 * `public T getExtension(String name)`
@@ -46,12 +45,12 @@ public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
             loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
         }
         return loader;
-    }
+}
     
 private ExtensionLoader(Class<?> type) {
         this.type = type;
         objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
-    }
+}
 ```
 
 2. getExtension
@@ -75,9 +74,9 @@ public T getExtension(String name) {
             }
         }
         return (T) instance;
-    }
+}
 ```
-Some judgments and caching have been made in the getExtention method, and the main logic is in the createExtension method. Let's move on to the createExtention method.
+Some judgments and caching have been made in the getExtension method, and the main logic is in the createExtension method. Let's move on to the createExtension method.
 
 ```java
 private T createExtension(String name) {
@@ -106,7 +105,7 @@ The createExtension method has done the following:
 1. First, get the corresponding extension class according to name. Read the extension point configuration file from the `META-INF` folder under ClassPath.
 2. Use reflection to create an instance of an extended class.
 3. make dependency injection for the attributes of the extended class instance. That is, IoC.
-4. If there is a wrapper, add the wrapper. That is, AoP.
+4. If there is a wrapper, add the wrapper. That is, AOP.
 
 Let's focus on these four processes.
 1. Get the corresponding extension class according to name. Let’s read the code first:
@@ -126,8 +125,8 @@ private Map<String, Class<?>> getExtensionClasses() {
         return classes;
     }
 
-    // synchronized in getExtensionClasses
-    private Map<String, Class<?>> loadExtensionClasses() {
+// synchronized in getExtensionClasses
+private Map<String, Class<?>> loadExtensionClasses() {
         final SPI defaultAnnotation = type.getAnnotation(SPI.class);
         if (defaultAnnotation != null) {
             String value = defaultAnnotation.value();
@@ -145,7 +144,7 @@ private Map<String, Class<?>> getExtensionClasses() {
         loadFile(extensionClasses, DUBBO_DIRECTORY);
         loadFile(extensionClasses, SERVICES_DIRECTORY);
         return extensionClasses;
-    }
+}
 ```
 This process is very simple. Get the extension class from the cache first, and if it does not exist, load it from the configuration file. The path of the configuration file has been mentioned before:
 * `META-INF/dubbo/internal`
@@ -186,17 +185,17 @@ To accomplish the automatic assembly of dependencies of the extended instances,
 private ExtensionLoader(Class<?> type) {
         this.type = type;
         objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
-    }
+}
 ```
 ObjectFacore is also an extension, obtained through `ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()`.
 
 
 ![Dubbo-ExtensionFactory | left](https://raw.githubusercontent.com/vangoleo/wiki/master/dubbo/dubbo-extensionfactory.png "")
 
-ExtensionLoader includes three implementations:
-1. SpiExtensionLoader: use Dubbo's Spi to load Extension.
-2. SpringExtensionLoader: load Extension from the Spring container.
-3. AdaptiveExtensionLoader: adaptive AdaptiveExtensionLoader
+ExtensionFactory includes three implementations:
+1. SpiExtensionFactory: use Dubbo's Spi to load Extension.
+2. SpringExtensionFactory: load Extension from the Spring container.
+3. AdaptiveExtensionFactory: adaptive AdaptiveExtensionLoader
 
 Pay attention to the AdaptiveExtensionLoader here, the source code is as follows:
 
@@ -227,9 +226,9 @@ public class AdaptiveExtensionFactory implements ExtensionFactory {
 }
 ```
 The AdaptiveExtensionLoader class has @Adaptive annotations. As mentioned earlier, Dubbo creates an adaptive instance for each extension. If the extension class has @Adaptive annotations, it will use it as an adaptive class. If not, Dubbo will create one for us. So `ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension())` will return an AdaptiveExtensionLoader instance as an adaptive extension instance. 
-The AdaptiveExtentionLoader will iterate through all the ExtensionFactory implementations and try to load the extensions. If found, return. If not, continue to find it in the next ExtensionFactory. Dubbo has two ExtensionFactory built in, which are searched from Dubbo's own extension mechanism and Spring container. Since ExtensionFactory itself is also an extension point, we can implement our own ExtensionFactory to enable automatic assembly of Dubbo to support our custom components. For [...]
+The AdaptiveExtensionLoader will iterate through all the ExtensionFactory implementations and try to load the extensions. If found, return. If not, continue to find it in the next ExtensionFactory. Dubbo has two ExtensionFactory built in, which are searched from Dubbo's own extension mechanism and Spring container. Since ExtensionFactory itself is also an extension point, we can implement our own ExtensionFactory to enable automatic assembly of Dubbo to support our custom components. For [...]
 
-## AoP of Dubbo SPI advanced usage
+## AOP of Dubbo SPI advanced usage
 
 We often use AOP functionality when using Spring. Insert other logic before and after the method of the target class. For example, Spring AOP is usually used to implement logging, monitoring, and authentication, and so on. 
 Does Dubbo's extension mechanism also support similar features? The answer is yes. In Dubbo, there is a special class called the Wrapper class. It uses the wrapper class to wrap the original extension point instance through the decorator pattern, and then inserts additional logic before and after the original extension point implementation to implement AOP functionality. 
@@ -250,11 +249,11 @@ Class A has a constructor `public A(A a)`, and the argument to the constructor i
 
 ### How to configure the Wrapper class
 
-The Wipper class in Dubbo is also an extension point. Like other extension points, it is also configured in the `META-INF` folder. For example, the ProtocolFilterWrapper and ProtocolListenerWrapper in the previous example are configured in the path `dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol`:
+The Wrapper class in Dubbo is also an extension point. Like other extension points, it is also configured in the `META-INF` folder. For example, the ProtocolFilterWrapper and ProtocolListenerWrapper in the previous example are configured in the path `dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol`:
 ```text
-filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper
-listener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper
-mock=com.alibaba.dubbo.rpc.support.MockProtocol
+filter=org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper
+listener=org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper
+mock=org.apache.dubbo.rpc.support.MockProtocol
 ```
 When Dubbo loads the extension configuration file, there is a piece of code as follows:
 
@@ -270,7 +269,7 @@ try {
 } catch (NoSuchMethodException e) {}
 ```
 The meaning of this code is that if the extension class has a copy constructor, it will be saved for later use. The class that has the copy constructor is the Wrapper class. The parameter obtained by `clazz.getConstructor(type)` is the constructor of the extension point interface. Note that the parameter type of the constructor is an extension point interface, not an extension class. 
-Take Protocol as an example. The configuration file `dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol defines filter=com.alibaba.dubbo.rpc.protocol. ProtocolFilterWrapper`. 
+Take Protocol as an example. The configuration file `dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol defines filter=org.apache.dubbo.rpc.protocol. ProtocolFilterWrapper`. 
 The code of ProtocolFilterWrapper is as follows:
 
 ```java
@@ -285,6 +284,7 @@ public class ProtocolFilterWrapper implements Protocol {
         }
         this.protocol = protocol;
     }
+}
 ```
 ProtocolFilterWrapper has a constructor `public ProtocolFilterWrapper(Protocol protocol)`, and the parameter is the extension point Protocol. So it is a Wrapper class in the Dubbo extension mechanism. The ExtensionLoader will cache it. When creating Extension instances later, the ExtensionLoader use these wrapper classes to wrap the original Extension point in turn.
 
@@ -325,7 +325,7 @@ private Class<?> getAdaptiveExtensionClass() {
             return cachedAdaptiveClass;
         }
         return cachedAdaptiveClass = createAdaptiveExtensionClass();
-    }
+}
 ```
 Continue to read the createAdaptiveExtensionClass method. After a long journey, we finally come to a concrete realization. Look at this createAdaptiveExtensionClass method, which first generates the Java source code for the adaptive class, and then compile the source code into Java bytecode and load it into the JVM.
 
@@ -333,9 +333,9 @@ Continue to read the createAdaptiveExtensionClass method. After a long journey,
 private Class<?> createAdaptiveExtensionClass() {
         String code = createAdaptiveExtensionClassCode();
         ClassLoader classLoader = findClassLoader();
-        com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
+        org.apache.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(org.apache.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
         return compiler.compile(code, classLoader);
-    }
+}
 ```
 The default implementation of Compiler's code is javassist.
 
@@ -349,44 +349,44 @@ The createAdaptiveExtensionClassCode () method uses a StringBuilder to build Jav
 Below are the Java code example for Protocol adaptive class created by createAdaptiveExtensionClassCode method: 
 
 ```java
-package com.alibaba.dubbo.rpc;
+package org.apache.dubbo.rpc;
 
-import com.alibaba.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.extension.ExtensionLoader;
 
-public class Protocol$Adpative implements com.alibaba.dubbo.rpc.Protocol {
+public class Protocol$Adaptive implements org.apache.dubbo.rpc.Protocol {
     public void destroy() {
-        throw new UnsupportedOperationException("method public abstract void com.alibaba.dubbo.rpc.Protocol.destroy() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");
+        throw new UnsupportedOperationException("method public abstract void org.apache.dubbo.rpc.Protocol.destroy() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!");
     }
 
     public int getDefaultPort() {
-        throw new UnsupportedOperationException("method public abstract int com.alibaba.dubbo.rpc.Protocol.getDefaultPort() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");
+        throw new UnsupportedOperationException("method public abstract int org.apache.dubbo.rpc.Protocol.getDefaultPort() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!");
     }
 
-    public com.alibaba.dubbo.rpc.Exporter export(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.RpcException {
-        if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
+    public org.apache.dubbo.rpc.Exporter export(org.apache.dubbo.rpc.Invoker arg0) throws org.apache.dubbo.rpc.RpcException {
+        if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null");
         if (arg0.getUrl() == null)
-            throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");
-        com.alibaba.dubbo.common.URL url = arg0.getUrl();
+            throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null");
+        org.apache.dubbo.common.URL url = arg0.getUrl();
         String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());
         if (extName == null)
-            throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
-        com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
+            throw new IllegalStateException("Fail to get extension(org.apache.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
+        org.apache.dubbo.rpc.Protocol extension = (org.apache.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName);
         return extension.export(arg0);
     }
 
-    public com.alibaba.dubbo.rpc.Invoker refer(java.lang.Class arg0, com.alibaba.dubbo.common.URL arg1) throws com.alibaba.dubbo.rpc.RpcException {
+    public org.apache.dubbo.rpc.Invoker refer(java.lang.Class arg0, org.apache.dubbo.common.URL arg1) throws org.apache.dubbo.rpc.RpcException {
         if (arg1 == null) throw new IllegalArgumentException("url == null");
-        com.alibaba.dubbo.common.URL url = arg1;
+        org.apache.dubbo.common.URL url = arg1;
         String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());
         if (extName == null)
-            throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
-        com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
+            throw new IllegalStateException("Fail to get extension(org.apache.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
+        org.apache.dubbo.rpc.Protocol extension = (org.apache.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName);
         return extension.refer(arg0, arg1);
     }
 }
 ```
 The general logic is the same as at the beginning. The parameters are parsed through the url, and the parsed logic is controlled by the value parameter of @adaptive, and then the extension points implementation are obtained according to the name of the extension point. And then finally make the call. If you want to know the specific construction logic of .Java code, you can see the complete implementation of `createAdaptiveExtensionClassCode`. 
-In the generated Protocol$Adpative, both the getDefaultPort and destroy methods are found to throw the exception directly. Why? Take a look at the source code of Protocol:
+In the generated Protocol$Adaptive, both the getDefaultPort and destroy methods are found to throw the exception directly. Why? Take a look at the source code of Protocol:
 
 ```java
 @SPI("dubbo")
@@ -401,6 +401,7 @@ public interface Protocol {
     <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
 
     void destroy();
+}
 ```
-As you can see, there are four methods in the Protocol interface, but only the methods of export and refer use the @adaptive annotation. Dubbo automatically generates adaptive instances, and only the methods modified by @Adaptive has a specific implementation. Therefore, in the Protocol$Adpative class, only the export and refer methods have specific implementations, and the rest of the methods throw exceptions.
+As you can see, there are four methods in the Protocol interface, but only the methods of export and refer use the @Adaptive annotation. Dubbo automatically generates adaptive instances, and only the methods modified by @Adaptive has a specific implementation. Therefore, in the Protocol$Adaptive class, only the export and refer methods have specific implementations, and the rest of the methods throw exceptions.
 
diff --git a/blog/zh-cn/introduction-to-dubbo-spi-2.md b/blog/zh-cn/introduction-to-dubbo-spi-2.md
index 1cff7f9..38f234d 100644
--- a/blog/zh-cn/introduction-to-dubbo-spi-2.md
+++ b/blog/zh-cn/introduction-to-dubbo-spi-2.md
@@ -9,8 +9,8 @@ description: 本文介绍了SPI扩展机制的实现原理与细节。
 在[Dubbo可扩展机制实战](./introduction-to-dubbo-spi.md)中,我们了解了Dubbo扩展机制的一些概念,初探了Dubbo中LoadBalance的实现,并自己实现了一个LoadBalance。是不是觉得Dubbo的扩展机制很不错呀,接下来,我们就深入Dubbo的源码,一睹庐山真面目。
 
 ## ExtensionLoader
-ExtentionLoader是最核心的类,负责扩展点的加载和生命周期管理。我们就以这个类开始吧。
-Extension的方法比较多,比较常用的方法有:
+ExtensionLoader 是最核心的类,负责扩展点的加载和生命周期管理。我们就以这个类开始吧。
+ExtensionLoader 的方法比较多,比较常用的方法有:
 * `public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type)`
 * `public T getExtension(String name)`
 * `public T getAdaptiveExtension()`
@@ -43,12 +43,12 @@ public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
             loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
         }
         return loader;
-    }
+}
     
 private ExtensionLoader(Class<?> type) {
         this.type = type;
         objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
-    }
+}
 ```
 
 2. getExtension方法
@@ -72,9 +72,9 @@ public T getExtension(String name) {
             }
         }
         return (T) instance;
-    }
+}
 ```
-getExtention方法中做了一些判断和缓存,主要的逻辑在createExtension方法中。我们继续看createExtention方法。
+getExtension 方法中做了一些判断和缓存,主要的逻辑在 createExtension 方法中。我们继续看 createExtension 方法。
 
 ```java
 private T createExtension(String name) {
@@ -102,8 +102,8 @@ private T createExtension(String name) {
 createExtension方法做了以下事情:
 1. 先根据name来得到对应的扩展类。从ClassPath下`META-INF`文件夹下读取扩展点配置文件。
 2. 使用反射创建一个扩展类的实例
-3. 对扩展类实例的属性进行依赖注入,即IoC。
-4. 如果有wrapper,添加wrapper。即AoP。
+3. 对扩展类实例的属性进行依赖注入,即IOC。
+4. 如果有wrapper,添加wrapper。即AOP。
 
 下面我们来重点看下这4个过程
 1. 根据name获取对应的扩展类
@@ -122,10 +122,10 @@ private Map<String, Class<?>> getExtensionClasses() {
             }
         }
         return classes;
-    }
+}
 
-    // synchronized in getExtensionClasses
-    private Map<String, Class<?>> loadExtensionClasses() {
+// synchronized in getExtensionClasses
+private Map<String, Class<?>> loadExtensionClasses() {
         final SPI defaultAnnotation = type.getAnnotation(SPI.class);
         if (defaultAnnotation != null) {
             String value = defaultAnnotation.value();
@@ -143,7 +143,7 @@ private Map<String, Class<?>> getExtensionClasses() {
         loadFile(extensionClasses, DUBBO_DIRECTORY);
         loadFile(extensionClasses, SERVICES_DIRECTORY);
         return extensionClasses;
-    }
+}
 ```
 过程很简单,先从缓存中获取,如果没有,就从配置文件中加载。配置文件的路径就是之前提到的:
 * `META-INF/dubbo/internal`
@@ -194,12 +194,12 @@ objectFacory本身也是一个扩展,通过`ExtensionLoader.getExtensionLoader
 
 ![Dubbo-ExtensionFactory | left](https://raw.githubusercontent.com/vangoleo/wiki/master/dubbo/dubbo-extensionfactory.png "")
 
-ExtensionLoader有三个实现:
-1. SpiExtensionLoader:Dubbo自己的Spi去加载Extension
-2. SpringExtensionLoader:从Spring容器中去加载Extension
-3. AdaptiveExtensionLoader: 自适应的AdaptiveExtensionLoader
+ExtensionFactory 有三个实现:
+1. SpiExtensionFactory:Dubbo自己的Spi去加载Extension
+2. SpringExtensionFactory:从Spring容器中去加载Extension
+3. AdaptiveExtensionFactory: 自适应的AdaptiveExtensionLoader
 
-这里要注意AdaptiveExtensionLoader,源码如下:
+这里要注意 AdaptiveExtensionFactory,源码如下:
 
 ```java
 @Adaptive
@@ -228,9 +228,9 @@ public class AdaptiveExtensionFactory implements ExtensionFactory {
 }
 ```
 AdaptiveExtensionLoader类有@Adaptive注解。前面提到了,Dubbo会为每一个扩展创建一个自适应实例。如果扩展类上有@Adaptive,会使用该类作为自适应类。如果没有,Dubbo会为我们创建一个。所以`ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension())`会返回一个AdaptiveExtensionLoader实例,作为自适应扩展实例。
-AdaptiveExtentionLoader会遍历所有的ExtensionFactory实现,尝试着去加载扩展。如果找到了,返回。如果没有,在下一个ExtensionFactory中继续找。Dubbo内置了两个ExtensionFactory,分别从Dubbo自身的扩展机制和Spring容器中去寻找。由于ExtensionFactory本身也是一个扩展点,我们可以实现自己的ExtensionFactory,让Dubbo的自动装配支持我们自定义的组件。比如,我们在项目中使用了Google的guice这个IoC容器。我们可以实现自己的GuiceExtensionFactory,让Dubbo支持从guice容器中加载扩展。
+AdaptiveExtensionLoader会遍历所有的ExtensionFactory实现,尝试着去加载扩展。如果找到了,返回。如果没有,在下一个ExtensionFactory中继续找。Dubbo内置了两个ExtensionFactory,分别从Dubbo自身的扩展机制和Spring容器中去寻找。由于ExtensionFactory本身也是一个扩展点,我们可以实现自己的ExtensionFactory,让Dubbo的自动装配支持我们自定义的组件。比如,我们在项目中使用了Google的guice这个 IOC 容器。我们可以实现自己的GuiceExtensionFactory,让Dubbo支持从guice容器中加载扩展。
 
-## Dubbo SPI高级用法之AoP
+## Dubbo SPI高级用法之 AOP
 在用Spring的时候,我们经常会用到AOP功能。在目标类的方法前后插入其他逻辑。比如通常使用Spring AOP来实现日志,监控和鉴权等功能。
 Dubbo的扩展机制,是否也支持类似的功能呢?答案是yes。在Dubbo中,有一种特殊的类,被称为Wrapper类。通过装饰者模式,使用包装类包装原始的扩展点实例。在原始扩展点实现前后插入其他逻辑,实现AOP功能。
 
@@ -249,11 +249,11 @@ class A{
 
 ### 怎么配置Wrapper类
 
-在Dubbo中Wrapper类也是一个扩展点,和其他的扩展点一样,也是在`META-INF`文件夹中配置的。比如前面举例的ProtocolFilterWrapper和ProtocolListenerWrapper就是在路径`dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol`中配置的:
+在Dubbo中Wrapper类也是一个扩展点,和其他的扩展点一样,也是在`META-INF`文件夹中配置的。比如前面举例的ProtocolFilterWrapper和ProtocolListenerWrapper就是在路径`dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol`中配置的:
 ```text
-filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper
-listener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper
-mock=com.alibaba.dubbo.rpc.support.MockProtocol
+filter=org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper
+listener=org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper
+mock=org.apache.dubbo.rpc.support.MockProtocol
 ```
 在Dubbo加载扩展配置文件时,有一段如下的代码:
 
@@ -269,7 +269,7 @@ try {
 } catch (NoSuchMethodException e) {}
 ```
 这段代码的意思是,如果扩展类有复制构造函数,就把该类存起来,供以后使用。有复制构造函数的类就是Wrapper类。通过`clazz.getConstructor(type)`来获取参数是扩展点接口的构造函数。注意构造函数的参数类型是扩展点接口,而不是扩展类。
-以Protocol为例。配置文件`dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol`中定义了`filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper`。
+以Protocol为例。配置文件`dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol`中定义了`filter=org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper`。
 ProtocolFilterWrapper代码如下:
 
 ```java
@@ -284,6 +284,7 @@ public class ProtocolFilterWrapper implements Protocol {
         }
         this.protocol = protocol;
     }
+}
 ```
 ProtocolFilterWrapper有一个构造函数`public ProtocolFilterWrapper(Protocol protocol)`,参数是扩展点Protocol,所以它是一个Dubbo扩展机制中的Wrapper类。ExtensionLoader会把它缓存起来,供以后创建Extension实例的时候,使用这些包装类依次包装原始扩展点。
 
@@ -332,7 +333,7 @@ private Class<?> getAdaptiveExtensionClass() {
 private Class<?> createAdaptiveExtensionClass() {
         String code = createAdaptiveExtensionClassCode();
         ClassLoader classLoader = findClassLoader();
-        com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
+        org.apache.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(org.apache.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
         return compiler.compile(code, classLoader);
     }
 ```
@@ -348,44 +349,44 @@ createAdaptiveExtensionClassCode()方法中使用一个StringBuilder来构建自
 下面是使用createAdaptiveExtensionClassCode方法为Protocol创建的自适应类的Java代码范例:
 
 ```java
-package com.alibaba.dubbo.rpc;
+package org.apache.dubbo.rpc;
 
-import com.alibaba.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.extension.ExtensionLoader;
 
-public class Protocol$Adpative implements com.alibaba.dubbo.rpc.Protocol {
+public class Protocol$Adaptive implements org.apache.dubbo.rpc.Protocol {
     public void destroy() {
-        throw new UnsupportedOperationException("method public abstract void com.alibaba.dubbo.rpc.Protocol.destroy() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");
+        throw new UnsupportedOperationException("method public abstract void org.apache.dubbo.rpc.Protocol.destroy() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!");
     }
 
     public int getDefaultPort() {
-        throw new UnsupportedOperationException("method public abstract int com.alibaba.dubbo.rpc.Protocol.getDefaultPort() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");
+        throw new UnsupportedOperationException("method public abstract int org.apache.dubbo.rpc.Protocol.getDefaultPort() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!");
     }
 
-    public com.alibaba.dubbo.rpc.Exporter export(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.RpcException {
-        if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
+    public org.apache.dubbo.rpc.Exporter export(org.apache.dubbo.rpc.Invoker arg0) throws org.apache.dubbo.rpc.RpcException {
+        if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null");
         if (arg0.getUrl() == null)
-            throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");
-        com.alibaba.dubbo.common.URL url = arg0.getUrl();
+            throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null");
+        org.apache.dubbo.common.URL url = arg0.getUrl();
         String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());
         if (extName == null)
-            throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
-        com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
+            throw new IllegalStateException("Fail to get extension(org.apache.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
+        org.apache.dubbo.rpc.Protocol extension = (org.apache.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName);
         return extension.export(arg0);
     }
 
-    public com.alibaba.dubbo.rpc.Invoker refer(java.lang.Class arg0, com.alibaba.dubbo.common.URL arg1) throws com.alibaba.dubbo.rpc.RpcException {
+    public org.apache.dubbo.rpc.Invoker refer(java.lang.Class arg0, org.apache.dubbo.common.URL arg1) throws org.apache.dubbo.rpc.RpcException {
         if (arg1 == null) throw new IllegalArgumentException("url == null");
-        com.alibaba.dubbo.common.URL url = arg1;
+        org.apache.dubbo.common.URL url = arg1;
         String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());
         if (extName == null)
-            throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
-        com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
+            throw new IllegalStateException("Fail to get extension(org.apache.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
+        org.apache.dubbo.rpc.Protocol extension = (org.apache.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName);
         return extension.refer(arg0, arg1);
     }
 }
 ```
 大致的逻辑和开始说的一样,通过url解析出参数,解析的逻辑由@Adaptive的value参数控制,然后再根据得到的扩展点名获取扩展点实现,然后进行调用。如果大家想知道具体的构建.java代码的逻辑,可以看`createAdaptiveExtensionClassCode`的完整实现。
-在生成的Protocol$Adpative中,发现getDefaultPort和destroy方法都是直接抛出异常的,这是为什么呢?来看看Protocol的源码
+在生成的 Protocol$Adaptive 中,发现getDefaultPort和destroy方法都是直接抛出异常的,这是为什么呢?来看看Protocol的源码
 
 ```java
 @SPI("dubbo")
@@ -400,5 +401,6 @@ public interface Protocol {
     <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
 
     void destroy();
+}
 ```
-可以看到Protocol接口中有4个方法,但只有export和refer两个方法使用了@Adaptive注解。Dubbo自动生成的自适应实例,只有@Adaptive修饰的方法才有具体的实现。所以,Protocol$Adpative类中,也只有export和refer这两个方法有具体的实现,其余方法都是抛出异常。
+可以看到Protocol接口中有4个方法,但只有export和refer两个方法使用了@Adaptive注解。Dubbo自动生成的自适应实例,只有@Adaptive修饰的方法才有具体的实现。所以,Protocol$Adaptive 类中,也只有export和refer这两个方法有具体的实现,其余方法都是抛出异常。