mirror of
https://gitee.com/devlive-community/datacap.git
synced 2024-11-29 18:48:23 +08:00
feat(plugin): support annotation plugin
This commit is contained in:
parent
a9ce7e989c
commit
2ef0f46876
@ -177,7 +177,7 @@ public abstract class Plugin
|
||||
|
||||
// 同时使用SPI和注解两种方式加载服务
|
||||
// Load services using both SPI and annotation methods
|
||||
ServiceBindings bindings = null;
|
||||
ServiceBindings bindings;
|
||||
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (pluginClassLoader != null) {
|
||||
bindings = ServiceSpiLoader.loadServices(serviceType, basePackage, pluginClassLoader);
|
||||
|
@ -7,24 +7,22 @@ import io.edurt.datacap.common.utils.DateUtils;
|
||||
import io.edurt.datacap.plugin.loader.PluginClassLoader;
|
||||
import io.edurt.datacap.plugin.loader.PluginLoaderFactory;
|
||||
import io.edurt.datacap.plugin.utils.PluginClassLoaderUtils;
|
||||
import io.edurt.datacap.plugin.utils.VersionUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Slf4j
|
||||
@ -54,6 +52,10 @@ public class PluginManager
|
||||
// Temporary directory prefix
|
||||
private static final String TEMP_DIR_PREFIX = "plugin_install_";
|
||||
|
||||
// 默认版本
|
||||
// Default version
|
||||
private static final String DEFAULT_VERSION = "1.0.0";
|
||||
|
||||
public PluginManager(PluginConfigure config)
|
||||
{
|
||||
this.config = config;
|
||||
@ -461,7 +463,7 @@ public class PluginManager
|
||||
|
||||
// 获取插件版本(可以从配置文件或清单文件中读取)
|
||||
// Get plugin version (can be read from config or manifest file)
|
||||
String pluginVersion = getPluginVersion(pluginDir);
|
||||
String pluginVersion = VersionUtils.determinePluginVersion(pluginDir);
|
||||
log.debug("Found plugin version: {}", pluginVersion);
|
||||
|
||||
// 创建插件专用类加载器
|
||||
@ -488,10 +490,10 @@ public class PluginManager
|
||||
|
||||
PluginMetadata pluginMetadata = PluginMetadata.builder()
|
||||
.name(pluginName)
|
||||
.version(module.getVersion())
|
||||
.version(Objects.equals(module.getVersion(), DEFAULT_VERSION) ? module.getPluginClassLoader().getPluginVersion() : module.getVersion())
|
||||
.location(pluginDir)
|
||||
.state(PluginState.CREATED)
|
||||
.classLoader(loader)
|
||||
.classLoader(module.getPluginClassLoader() == null ? loader : module.getPluginClassLoader())
|
||||
.loaderName(module.getClassLoader())
|
||||
.instance(module)
|
||||
.type(module.getType())
|
||||
@ -520,79 +522,6 @@ public class PluginManager
|
||||
}
|
||||
}
|
||||
|
||||
// 获取插件版本
|
||||
// Get plugin version
|
||||
private String getPluginVersion(Path pluginDir)
|
||||
{
|
||||
// 这里可以实现从配置文件或清单文件中读取版本号的逻辑
|
||||
// Here you can implement logic to read version number from config or manifest file
|
||||
try {
|
||||
// 优先从 plugin.properties 读取
|
||||
// Read from plugin.properties first
|
||||
Path propertiesFile = pluginDir.resolve("plugin.properties");
|
||||
if (Files.exists(propertiesFile)) {
|
||||
// 读取属性文件实现
|
||||
// Implement properties file reading
|
||||
return readVersionFromProperties(propertiesFile);
|
||||
}
|
||||
|
||||
// 其次从 MANIFEST.MF 读取
|
||||
// Then read from MANIFEST.MF
|
||||
Path manifestFile = pluginDir.resolve("META-INF/MANIFEST.MF");
|
||||
if (Files.exists(manifestFile)) {
|
||||
return readVersionFromManifest(manifestFile);
|
||||
}
|
||||
|
||||
// 最后从 pom.xml 读取
|
||||
// Finally read from pom.xml
|
||||
Path pomFile = pluginDir.resolve("pom.xml");
|
||||
if (Files.exists(pomFile)) {
|
||||
return readVersionFromPom(pomFile);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Failed to read plugin version from: {}", pluginDir, e);
|
||||
}
|
||||
|
||||
// 如果都读取失败,返回默认版本
|
||||
// Return default version if all reads fail
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
private String readVersionFromProperties(Path propertiesFile)
|
||||
{
|
||||
// TODO: 实现从 properties 文件读取版本号
|
||||
// Implement reading version from properties file
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
private String readVersionFromManifest(Path manifestFile)
|
||||
throws IOException
|
||||
{
|
||||
// TODO: 实现从 MANIFEST.MF 读取版本号
|
||||
// Implement reading version from MANIFEST.MF
|
||||
ClassLoader loader = getClass().getClassLoader();
|
||||
|
||||
Enumeration<URL> resources = loader.getResources("META-INF/MANIFEST.MF");
|
||||
while (resources.hasMoreElements()) {
|
||||
try (InputStream is = resources.nextElement().openStream()) {
|
||||
Manifest manifest = new Manifest(is);
|
||||
String version = manifest.getMainAttributes().getValue("Implementation-Version");
|
||||
if (version != null) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
private String readVersionFromPom(Path pomFile)
|
||||
{
|
||||
// TODO: 实现从 pom.xml 读取版本号
|
||||
// Implement reading version from pom.xml
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
// 关闭插件类加载器
|
||||
// Close plugin class loader
|
||||
private void closePluginClassLoader(PluginMetadata pluginMetadata)
|
||||
|
@ -6,7 +6,8 @@ public enum SpiType
|
||||
DIRECTORY("Directory"),
|
||||
POM("Pom"),
|
||||
PROPERTIES("Properties"),
|
||||
SPI("Spi");
|
||||
SPI("Spi"),
|
||||
INJECT("Inject");
|
||||
|
||||
private String name;
|
||||
|
||||
|
@ -0,0 +1,27 @@
|
||||
package io.edurt.datacap.plugin.annotation;
|
||||
|
||||
import io.edurt.datacap.plugin.PluginType;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface InjectPlugin
|
||||
{
|
||||
/**
|
||||
* 插件名称
|
||||
* Plugin name
|
||||
*/
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* 插件版本
|
||||
* Plugin version
|
||||
*/
|
||||
String version() default "1.0.0";
|
||||
|
||||
PluginType type() default PluginType.CONNECTOR;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package io.edurt.datacap.plugin.service;
|
||||
package io.edurt.datacap.plugin.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
@ -0,0 +1,94 @@
|
||||
package io.edurt.datacap.plugin.loader;
|
||||
|
||||
import io.edurt.datacap.plugin.Plugin;
|
||||
import io.edurt.datacap.plugin.PluginContextManager;
|
||||
import io.edurt.datacap.plugin.SpiType;
|
||||
import io.edurt.datacap.plugin.scanner.PluginAnnotationScanner;
|
||||
import io.edurt.datacap.plugin.utils.PluginClassLoaderUtils;
|
||||
import io.edurt.datacap.plugin.utils.VersionUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public class InjectPluginLoader
|
||||
implements PluginLoader
|
||||
{
|
||||
private final PluginAnnotationScanner scanner;
|
||||
|
||||
public InjectPluginLoader()
|
||||
{
|
||||
this.scanner = new PluginAnnotationScanner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpiType getType()
|
||||
{
|
||||
return SpiType.INJECT;
|
||||
}
|
||||
|
||||
private Path getEffectivePluginPath(Path originalPath)
|
||||
{
|
||||
if (originalPath.endsWith("classes")) {
|
||||
return originalPath.getParent();
|
||||
}
|
||||
return originalPath;
|
||||
}
|
||||
|
||||
private String getEffectivePluginName(Path path)
|
||||
{
|
||||
if (path.getFileName().toString().equals("target")) {
|
||||
return path.getParent().getFileName().toString();
|
||||
}
|
||||
if (path.getFileName().toString().equals("classes")) {
|
||||
return path.getParent().getParent().getFileName().toString();
|
||||
}
|
||||
return path.getFileName().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Plugin> load(Path path)
|
||||
{
|
||||
try {
|
||||
if (isExcludedPath(path)) {
|
||||
log.debug("Skipping excluded directory: {}", path);
|
||||
return List.of();
|
||||
}
|
||||
|
||||
// 获取实际的插件路径(用于版本检测)
|
||||
// Get actual plugin path (used for version detection)
|
||||
Path effectivePath = getEffectivePluginPath(path);
|
||||
// 获取正确的插件名称
|
||||
// Get correct plugin name
|
||||
String pluginName = getEffectivePluginName(effectivePath);
|
||||
String version = VersionUtils.determinePluginVersion(effectivePath);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Loading plugin - Path: {}, Effective Path: {}, Name: {}, Version: {}", path, effectivePath, pluginName, version);
|
||||
}
|
||||
|
||||
// 创建插件专用类加载器
|
||||
// Create plugin-specific class loader
|
||||
PluginClassLoader classLoader = PluginClassLoaderUtils.createClassLoader(
|
||||
path,
|
||||
pluginName,
|
||||
version
|
||||
);
|
||||
|
||||
return PluginContextManager.runWithClassLoader(classLoader, () -> {
|
||||
List<Plugin> plugins = scanner.scanPlugins(path, classLoader);
|
||||
|
||||
// 设置插件的类加载器
|
||||
// Set class loader for plugins
|
||||
plugins.forEach(plugin -> plugin.setPluginClassLoader(classLoader));
|
||||
|
||||
return plugins;
|
||||
});
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Failed to load inject plugins from path: {}", path, e);
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
}
|
@ -3,11 +3,80 @@ package io.edurt.datacap.plugin.loader;
|
||||
import io.edurt.datacap.plugin.Plugin;
|
||||
import io.edurt.datacap.plugin.SpiType;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface PluginLoader
|
||||
{
|
||||
Set<String> EXCLUDED_DIRS = new HashSet<>()
|
||||
{{
|
||||
// Maven 相关目录
|
||||
// Maven related directories
|
||||
add("target/test-classes");
|
||||
add("target/generated-sources");
|
||||
add("target/generated-test-sources");
|
||||
add("target/maven-status");
|
||||
add("target/maven-archiver");
|
||||
add("target/surefire-reports");
|
||||
add("target/reports");
|
||||
add("target/javadoc-bundle-options");
|
||||
|
||||
// 版本控制和 IDE 目录
|
||||
// Version control and IDE directories
|
||||
add(".git");
|
||||
add(".idea");
|
||||
add(".vscode");
|
||||
add(".settings");
|
||||
add(".project");
|
||||
add(".classpath");
|
||||
|
||||
// 依赖目录
|
||||
// Dependency directories
|
||||
add("node_modules");
|
||||
|
||||
// SPI 特有的排除目录
|
||||
// SPI-specific exclusion directories
|
||||
add("META-INF/services/test");
|
||||
add("META-INF/maven");
|
||||
add("META-INF/versions");
|
||||
|
||||
// 源码目录
|
||||
// Source code directory
|
||||
add("src/main/java");
|
||||
add("src/main/kotlin");
|
||||
add("src/main/resources");
|
||||
add("src/test");
|
||||
add("src/test/java");
|
||||
add("src/test/kotlin");
|
||||
add("src/test/resources");
|
||||
}};
|
||||
|
||||
/**
|
||||
* 检查路径是否应该被排除
|
||||
* Check if the path should be excluded
|
||||
*/
|
||||
default boolean isExcludedPath(Path path)
|
||||
{
|
||||
String pathStr = path.toString();
|
||||
return EXCLUDED_DIRS.stream()
|
||||
.anyMatch(dir -> pathStr.contains(dir.replace('/', File.separatorChar)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查目录是否有效且不在排除列表中
|
||||
* Check if the directory is valid and not in the exclusion list
|
||||
*/
|
||||
default boolean isValidDirectory(Path path)
|
||||
{
|
||||
return Files.exists(path) &&
|
||||
Files.isDirectory(path) &&
|
||||
!isExcludedPath(path);
|
||||
}
|
||||
|
||||
// 获取加载器类型
|
||||
// Get loader type
|
||||
SpiType getType();
|
||||
|
@ -7,6 +7,7 @@ import io.edurt.datacap.plugin.utils.PluginClassLoaderUtils;
|
||||
import io.edurt.datacap.plugin.utils.VersionUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
@ -27,6 +28,13 @@ public class SpiPluginLoader
|
||||
public List<Plugin> load(Path path)
|
||||
{
|
||||
try {
|
||||
// 检查路径是否有效
|
||||
// Check if the path is valid
|
||||
if (!isValidDirectory(path)) {
|
||||
log.debug("Skipping excluded or invalid directory: {}", path);
|
||||
return List.of();
|
||||
}
|
||||
|
||||
// 获取目录名作为插件名
|
||||
// Get directory name as plugin name
|
||||
String pluginName = path.getFileName().toString();
|
||||
@ -43,11 +51,20 @@ public class SpiPluginLoader
|
||||
return PluginContextManager.runWithClassLoader(classLoader, () -> {
|
||||
ServiceLoader<Plugin> serviceLoader = ServiceLoader.load(Plugin.class, classLoader);
|
||||
List<Plugin> plugins = StreamSupport.stream(serviceLoader.spliterator(), false)
|
||||
.filter(plugin -> {
|
||||
// 检查插件类是否来自排除目录
|
||||
// Check if the plugin class is from an excluded directory
|
||||
String className = plugin.getClass().getName();
|
||||
Path classPath = Path.of(className.replace('.', File.separatorChar) + ".class");
|
||||
return !isExcludedPath(classPath);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 设置插件的类加载器
|
||||
// Set class loader for plugins
|
||||
plugins.forEach(plugin -> plugin.setPluginClassLoader(classLoader));
|
||||
plugins.stream()
|
||||
.peek(plugin -> log.debug("Loaded SPI plugin: {} (version: {})", plugin.getClass().getName(), version))
|
||||
.forEach(plugin -> plugin.setPluginClassLoader(classLoader));
|
||||
|
||||
return plugins;
|
||||
});
|
||||
|
@ -0,0 +1,151 @@
|
||||
package io.edurt.datacap.plugin.scanner;
|
||||
|
||||
import io.edurt.datacap.plugin.Plugin;
|
||||
import io.edurt.datacap.plugin.annotation.InjectPlugin;
|
||||
import io.edurt.datacap.plugin.loader.PluginClassLoader;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Slf4j
|
||||
public class PluginAnnotationScanner
|
||||
{
|
||||
// 定义要排除的目录
|
||||
// Define directories to exclude
|
||||
private static final Set<String> EXCLUDED_DIRS = new HashSet<>()
|
||||
{{
|
||||
add("target/test-classes");
|
||||
add("target/generated-sources");
|
||||
add("target/generated-test-sources");
|
||||
add("target/maven-status");
|
||||
add("target/maven-archiver");
|
||||
add("target/surefire-reports");
|
||||
add(".git");
|
||||
add(".idea");
|
||||
add("node_modules");
|
||||
}};
|
||||
|
||||
/**
|
||||
* 扫描目录中的插件注解
|
||||
* Scan plugins in directory
|
||||
*/
|
||||
public List<Plugin> scanPlugins(Path directory, PluginClassLoader classLoader)
|
||||
{
|
||||
List<Plugin> plugins = new ArrayList<>();
|
||||
|
||||
try {
|
||||
// 获取要扫描的目录
|
||||
// Get directories to scan
|
||||
List<Path> scanDirs = new ArrayList<>();
|
||||
|
||||
// 检查主类目录
|
||||
// Check main classes directory
|
||||
Path mainClassesDir = directory;
|
||||
if (Files.exists(directory.resolve("target/classes"))) {
|
||||
mainClassesDir = directory.resolve("target/classes");
|
||||
}
|
||||
scanDirs.add(mainClassesDir);
|
||||
|
||||
// 扫描每个目录
|
||||
// Scan each directory
|
||||
for (Path scanDir : scanDirs) {
|
||||
try (Stream<Path> paths = Files.walk(scanDir)) {
|
||||
paths.filter(path -> !isExcludedPath(path))
|
||||
.filter(path -> path.toString().endsWith(".class"))
|
||||
.filter(path -> !path.toString().contains("$"))
|
||||
.forEach(path -> {
|
||||
try {
|
||||
String className = getClassName(scanDir, path);
|
||||
Class<?> cls = classLoader.loadClass(className);
|
||||
|
||||
// 检查是否有 @InjectPlugin 注解
|
||||
// Check if it has @InjectPlugin annotation
|
||||
InjectPlugin annotation = cls.getAnnotation(InjectPlugin.class);
|
||||
if (annotation != null) {
|
||||
processPluginClass(cls, annotation, plugins, classLoader);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.debug("Failed to load class: {}", path);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Failed to scan plugins in directory: {}", directory, e);
|
||||
}
|
||||
|
||||
return plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查路径是否应该被排除
|
||||
* Check if path should be excluded
|
||||
*/
|
||||
private boolean isExcludedPath(Path path)
|
||||
{
|
||||
String pathStr = path.toString();
|
||||
return EXCLUDED_DIRS.stream()
|
||||
.anyMatch(dir -> pathStr.contains(dir.replace('/', File.separatorChar)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理带有 @InjectPlugin 注解的类
|
||||
* Handle class with @InjectPlugin annotation
|
||||
*/
|
||||
private void processPluginClass(Class<?> cls, InjectPlugin annotation, List<Plugin> plugins,
|
||||
PluginClassLoader classLoader)
|
||||
{
|
||||
try {
|
||||
// 验证类是否实现了Plugin接口
|
||||
// Validate class implements Plugin interface
|
||||
if (!Plugin.class.isAssignableFrom(cls)) {
|
||||
log.warn("Class {} has @InjectPlugin annotation but doesn't implement Plugin interface", cls.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建插件实例
|
||||
// Create plugin instance
|
||||
Plugin plugin = (Plugin) cls.getDeclaredConstructor().newInstance();
|
||||
|
||||
// 设置插件元数据
|
||||
// Set plugin metadata
|
||||
String name = annotation.name().isEmpty() ? cls.getSimpleName() : annotation.name();
|
||||
|
||||
plugin.setPluginClassLoader(classLoader);
|
||||
plugins.add(plugin);
|
||||
|
||||
log.info("Found inject plugin: {} (version: {})", name, annotation.version());
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Failed to process plugin class: {}", cls.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类名
|
||||
* Get class name
|
||||
*/
|
||||
private String getClassName(Path baseDir, Path classFile)
|
||||
{
|
||||
// 获取相对路径
|
||||
// Get relative path
|
||||
String relativePath = baseDir.relativize(classFile).toString();
|
||||
|
||||
// 处理路径分隔符和移除.class扩展名
|
||||
// Handle path separators and remove .class extension
|
||||
String className = relativePath.replace(File.separatorChar, '.');
|
||||
if (className.startsWith("test-classes.")) {
|
||||
className = className.substring("test-classes.".length());
|
||||
}
|
||||
return className.replace(".class", "");
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
package io.edurt.datacap.plugin.service;
|
||||
package io.edurt.datacap.plugin.scanner;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.reflect.ClassPath;
|
||||
import io.edurt.datacap.plugin.Service;
|
||||
import io.edurt.datacap.plugin.annotation.InjectService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.IOException;
|
@ -2,6 +2,8 @@ package io.edurt.datacap.plugin.service;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import io.edurt.datacap.plugin.Service;
|
||||
import io.edurt.datacap.plugin.annotation.InjectService;
|
||||
import io.edurt.datacap.plugin.scanner.ServiceAnnotationScanner;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
|
@ -0,0 +1,16 @@
|
||||
package io.edurt.datacap.test;
|
||||
|
||||
import io.edurt.datacap.plugin.Plugin;
|
||||
import io.edurt.datacap.plugin.PluginType;
|
||||
import io.edurt.datacap.plugin.annotation.InjectPlugin;
|
||||
|
||||
@InjectPlugin
|
||||
public class AnnotationPlugin
|
||||
extends Plugin
|
||||
{
|
||||
@Override
|
||||
public PluginType getType()
|
||||
{
|
||||
return PluginType.CONNECTOR;
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package io.edurt.datacap.test;
|
||||
|
||||
import io.edurt.datacap.plugin.service.InjectService;
|
||||
import io.edurt.datacap.plugin.annotation.InjectService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
|
@ -2,6 +2,8 @@ package io.edurt.datacap.test;
|
||||
|
||||
import io.edurt.datacap.plugin.PluginConfigure;
|
||||
import io.edurt.datacap.plugin.PluginManager;
|
||||
import io.edurt.datacap.plugin.loader.InjectPluginLoader;
|
||||
import io.edurt.datacap.plugin.loader.PluginLoaderFactory;
|
||||
import io.edurt.datacap.plugin.utils.PluginPathUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
@ -19,8 +21,10 @@ public class LocalPluginTest
|
||||
Path projectRoot = PluginPathUtils.findProjectRoot();
|
||||
PluginConfigure config = PluginConfigure.builder()
|
||||
.pluginsDir(projectRoot.resolve("test/datacap-test-plugin"))
|
||||
.scanDepth(2)
|
||||
.build();
|
||||
|
||||
PluginLoaderFactory.registerLoader(new InjectPluginLoader());
|
||||
pluginManager = new PluginManager(config);
|
||||
pluginManager.start();
|
||||
}
|
||||
@ -30,4 +34,14 @@ public class LocalPluginTest
|
||||
{
|
||||
Assert.assertFalse(pluginManager.getPlugin("Local").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationPlugin()
|
||||
{
|
||||
pluginManager.getPlugin("Annotation")
|
||||
.ifPresent(value -> {
|
||||
LogService logService = value.getService(LogService.class);
|
||||
logService.print();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user