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]