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

mikexue pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-eventmesh.git


The following commit(s) were added to refs/heads/develop by this push:
     new 4bc1a0a  Add SPI design docs (#480)
4bc1a0a is described below

commit 4bc1a0a3acba96ca65f956c14e7b5b8489e10cca
Author: Wenjun Ruan <[email protected]>
AuthorDate: Wed Aug 4 14:58:49 2021 +0800

    Add SPI design docs (#480)
---
 docs/cn/features/spi.zh-CN.md | 112 ++++++++++++++++++++++++++++++++++++++++
 docs/en/features/spi.en-US.md | 117 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 229 insertions(+)

diff --git a/docs/cn/features/spi.zh-CN.md b/docs/cn/features/spi.zh-CN.md
new file mode 100644
index 0000000..a75ae42
--- /dev/null
+++ b/docs/cn/features/spi.zh-CN.md
@@ -0,0 +1,112 @@
+# EventMesh SPI
+
+## 介绍
+
+为了提高扩展性,EventMesh通过引入SPI(Service Provider 
Interface)机制,能够在运行时自动寻找扩展接口的具体实现类,动态加载。
+在EventMesh中,一切扩展点都利用SPI采用插件的实现方式,用户可以通过实现扩展接口,开发自定义的插件,在运行时通过简单的配置,声明式的选择所需要运行的插件。
+
+## eventmesh-spi模块
+
+SPI相关的代码位于eventmesh-spi模块下,其中主要包括EventMeshExtensionFactory, EventMeshSPI, 
ExtensionClassLoader这三个类。
+
+### EventMeshSPI
+
+EventMeshSPI是SPI注解,所有需要采用SPI实现扩展的接口都需要使用@EventMeshSPI注解标记。
+
+```java
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+public @interface EventMeshSPI {
+
+    /**
+     * If true, the spi instance is singleton
+     */
+    boolean isSingleton() default false;
+
+}
+```
+
+这么做的原因是可以通过注解的方式声明接口为SPI扩展接口,提高代码的可读性。同时,@EventMeshSPI注解中包含一个isSingleton属性,
+用来声明该扩展接口是否采用单例的实现方式,如果为true,那么该接口的实现类将会使用单例的实现方式,在一个JVM进程中全局唯一。
+
+### EventMeshExtensionFactory
+
+EventMeshExtensionFactory是SPI实现类的获取工厂,包含一个静态方法getExtension(Class<T> 
extensionType, String extensionName),
+接收扩展接口字节码对象和扩展实例名称,用于获取扩展接口的具体实现类。
+
+```java
+public enum EventMeshExtensionFactory {
+  ;
+    /**
+     * @param extensionType extension plugin class type
+     * @param extensionName extension instance name
+     * @param <T>           the type of the plugin
+     * @return plugin instance
+     */
+    public static <T> T getExtension(Class<T> extensionType, String 
extensionName) { 
+    ...
+    }
+}
+```
+
+所有需要获取扩展实现的地方都应该通过EventMeshExtensionFactory获取。
+
+### ExtensionClassLoader
+
+ExtensionClassLoader是扩展接口实现类的加载接口,包含两个实现子类MetaInfExtensionClassLoader和JarExtensionClassLoader。
+
+```java
+/**
+ * Load extension class
+ * <ul>
+ *     <li>{@link MetaInfExtensionClassLoader}</li>
+ *     <li>{@link JarExtensionClassLoader}</li>
+ * </ul>
+ */
+public interface ExtensionClassLoader {
+
+    /**
+     * load
+     *
+     * @param extensionType extension type class
+     * @param <T>           extension type
+     * @return extension instance name to extension instance class
+     */
+    <T> Map<String, Class<?>> loadExtensionClass(Class<T> extensionType);
+}
+```
+
+MetaInfExtensionClassLoader用于从classPath直接加载实现类,JarExtensionClassLoader用于从配置目录下通过加载Jar包的方式加载实现类,未来可能还会提供通过从Maven仓库下加载实现类。
+
+## SPI使用示例
+
+下面以eventmesh-connector-plugin为例,介绍SPI具体的使用过程。
+
+首先定义一个eventmesh-connector-api模块,并且定义扩展接口MeshMQProducer。在MeshMQProducer接口上使用@EventMeshSPI注解进行声明,表明该接口是一个SPI扩展接口
+
+```java
+@EventMeshSPI(isSingleton = false)
+public interface MeshMQProducer extends Producer {
+...
+}
+```
+
+eventmesh-connector-rocketmq模块中包含采用rocketmq的具体实现方式RocketMQProducerImpl。
+
+```java
+public class RocketMQProducerImpl implements MeshMQProducer {
+...
+}
+```
+
+同时,还需要在eventmesh-connector-rocketmq模块中resource/META-INF/eventmesh目录下创建文件名为SPI接口全限定名的文件
+org.apache.eventmesh.api.producer.MeshMQProducer
+
+文件内容为扩展实例名和对应的实例全类名
+
+```properties
+rocketmq=org.apache.eventmesh.connector.rocketmq.producer.RocketMQProducerImpl
+```
+
+至此,一个SPI扩展模块就完成了。在使用的时候只需要通过EventMeshExtensionFactory.getExtension(MeshMQProducer.class,
 “rocketmq”)就可以获取RocketMQProducerImpl实现类。
\ No newline at end of file
diff --git a/docs/en/features/spi.en-US.md b/docs/en/features/spi.en-US.md
new file mode 100644
index 0000000..17407f9
--- /dev/null
+++ b/docs/en/features/spi.en-US.md
@@ -0,0 +1,117 @@
+# EventMesh SPI
+
+## Introduction
+
+In order to improve scalability,EventMesh introduce the SPI(Service Provider 
Interface)mechanism, which can help to automatically find the concrete 
implementation
+class of the extended interface at runtime and load it dynamically. In 
EventMesh, all extension modules are implemented by using plugin. 
+User can develop custom plugins by simply implementing extended interfaces, 
and select the plugin to be run at runtime by simply declare at configuration.
+
+## eventmesh-spi module
+
+The implementation of SPI is at eventmesh-spi module, there are three main 
classes `EventMeshSPI`, `EventMeshExtensionFactory` and `ExtensionClassLoader`.
+
+### EventMeshSPI
+
+EventMeshSPI is an SPI declaration annotation, all extended interface that 
want to be implemented should be declared by @EventMeshSPI.
+
+```java
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+public @interface EventMeshSPI {
+
+    /**
+     * If true, the spi instance is singleton
+     */
+    boolean isSingleton() default false;
+
+}
+```
+Use annotation to declare the interface is an SPI extended interface can 
improve the readability of the code.
+On the other hand, @EventMeshSPI contains a isSingleton attribute which used 
to declare whether the extension instance is a singleton.
+If this attribute is true, that means the instance of this interface will be 
singleton.
+
+### EventMeshExtensionFactory
+
+EventMeshExtensionFactory is a factory used to get the SPI extension instance 
which contains a static method getExtension(Class<T> extensionType, String 
extensionName).
+
+```java
+public enum EventMeshExtensionFactory {
+  ;
+    /**
+     * @param extensionType extension plugin class type
+     * @param extensionName extension instance name
+     * @param <T>           the type of the plugin
+     * @return plugin instance
+     */
+    public static <T> T getExtension(Class<T> extensionType, String 
extensionName) { 
+    ...
+    }
+}
+```
+
+If you want to get the extension instance, you should use 
EventMeshExtensionFactory.
+
+### ExtensionClassLoader
+
+ExtensionClassLoader is used to load extension instance classed, it has two 
subclass MetaInfExtensionClassLoader and JarExtensionClassLoader.
+
+```java
+/**
+ * Load extension class
+ * <ul>
+ *     <li>{@link MetaInfExtensionClassLoader}</li>
+ *     <li>{@link JarExtensionClassLoader}</li>
+ * </ul>
+ */
+public interface ExtensionClassLoader {
+
+    /**
+     * load
+     *
+     * @param extensionType extension type class
+     * @param <T>           extension type
+     * @return extension instance name to extension instance class
+     */
+    <T> Map<String, Class<?>> loadExtensionClass(Class<T> extensionType);
+}
+```
+
+MetaInfExtensionClassLoader used to load class from classPath, and 
JarExtensionClassLoader used to load class from extension jar on the plugin 
directory.
+In the future, we might support the implementation to load from the maven 
repository.
+
+## SPI use case
+
+The following is an example of how to use the SPI to declare a plugin.
+
+First, we create an eventmesh-connector-api module, and define the extension 
interface MeshMQProducer, and we use @EventMeshSPI on the MeshMQProducer, 
+which indicates the MeshMQProducer is an SPI interface.
+
+```java
+@EventMeshSPI(isSingleton = false)
+public interface MeshMQProducer extends Producer {
+...
+}
+```
+
+Then we create an eventmesh-connector-rocketmq module, which contains the 
concrete implementation named RocketMQProducerImpl.
+
+```java
+public class RocketMQProducerImpl implements MeshMQProducer {
+...
+}
+```
+
+At the same time, we need to create a file with the full qualified name of the 
SPI interface under the resource/META-INF/eventmesh directory 
+in the eventmesh-connector-rocketmq module.
+
+org.apache.eventmesh.api.producer.MeshMQProducer
+
+The content of the file is the extension instance name and the corresponding 
instance full class name
+
+```properties
+rocketmq=org.apache.eventmesh.connector.rocketmq.producer.RocketMQProducerImpl
+```
+
+At this point, an SPI expansion module is complete. We can use 
`EventMeshExtensionFactory.getExtension(MeshMQProducer.class, “rocketmq”)`
+to get the RocketMQProducerImpl instance.
\ No newline at end of file

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to