插件加载调整

This commit is contained in:
bwcx_jzy 2021-12-24 14:42:31 +08:00
parent 54fe8003da
commit bcf75e8f9c
No known key found for this signature in database
GPG Key ID: 5E48E9372088B9E5
10 changed files with 153 additions and 103 deletions

View File

@ -22,11 +22,19 @@
*/
package io.jpom.plugin;
import cn.hutool.core.util.StrUtil;
/**
* 默认插件
*
* @author bwcx_jzy
* @since 2021/12/22
*/
public enum DefaultPlugin {
/**
* null
*/
NULL(StrUtil.EMPTY),
/**
* web hook
*/

View File

@ -30,13 +30,4 @@ package io.jpom.plugin;
*/
public interface IDefaultPlugin extends IPlugin {
/**
* 默认插件排序到最后
*
* @return max
*/
@Override
default int order() {
return Integer.MAX_VALUE;
}
}

View File

@ -53,29 +53,4 @@ public interface IPlugin {
default boolean check(String type, Object main, Map<String, Object> parameter) {
throw new RuntimeException("Not implements");
}
/**
* 插件的名字
*
* @return 名称
*/
String name();
/**
* 插件父级
*
* @return 父级名称
*/
default String parent() {
return null;
}
/**
* 排序值
*
* @return 值越小排到前面 正序
*/
default int order() {
return Integer.MIN_VALUE;
}
}

View File

@ -0,0 +1,38 @@
package io.jpom.plugin;
import cn.hutool.core.util.StrUtil;
import java.lang.annotation.*;
/**
* 插件配置 相关属性注解
*
* @author bwcx_jzy
* @since 2021/12/24
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PluginConfig {
/**
* 是否为原生对象原生对象将使用 默认构造方法创建单利对象
*
* @return 默认 原生对象
*/
boolean nativeObject() default true;
/**
* 默认插件该字段优先级最低
*
* @return 插件名
*/
DefaultPlugin plugin() default DefaultPlugin.NULL;
/**
* 插件名该字段优先级高于 plugin
*
* @return 插件名
*/
String name() default StrUtil.EMPTY;
}

View File

@ -28,12 +28,12 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.JarClassLoader;
import cn.hutool.core.util.ClassLoaderUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import io.jpom.common.JpomManifest;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.util.Assert;
import java.io.File;
@ -52,7 +52,7 @@ import java.util.stream.Collectors;
public class PluginFactory implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private static final List<FeatureCallback> FEATURE_CALLBACKS = new ArrayList<>();
private static final Map<String, List<PluginItem>> PLUGIN_MAP = new ConcurrentHashMap<>();
private static final Map<String, List<PluginItemWrap>> PLUGIN_MAP = new ConcurrentHashMap<>();
/**
* 添加回调事件
@ -84,10 +84,10 @@ public class PluginFactory implements ApplicationContextInitializer<Configurable
* @return 插件对象
*/
public static IPlugin getPlugin(String name) {
List<PluginItem> pluginItems = PLUGIN_MAP.get(name);
PluginItem first = CollUtil.getFirst(pluginItems);
List<PluginItemWrap> pluginItemWraps = PLUGIN_MAP.get(name);
PluginItemWrap first = CollUtil.getFirst(pluginItemWraps);
Assert.notNull(first, "对应找到对应到插件:" + name);
return first.plugin;
return first.getPlugin();
}
/**
@ -103,14 +103,12 @@ public class PluginFactory implements ApplicationContextInitializer<Configurable
* 正式环境添加依赖
*/
private static void init() {
if (JpomManifest.getInstance().isDebug()) {
return;
}
File runPath = JpomManifest.getRunPath().getParentFile();
File plugin = FileUtil.file(runPath, "plugin");
if (!plugin.exists() || plugin.isFile()) {
return;
}
// 加载二级插件包
File[] dirFiles = plugin.listFiles(File::isDirectory);
if (dirFiles != null) {
for (File file : dirFiles) {
@ -125,6 +123,7 @@ public class PluginFactory implements ApplicationContextInitializer<Configurable
addPlugin(file.getName(), lib);
}
}
// 加载一级独立插件端包
File[] files = plugin.listFiles(pathname -> FileUtil.isFile(pathname) && FileUtil.JAR_FILE_EXT.equalsIgnoreCase(FileUtil.extName(pathname)));
if (files != null) {
for (File file : files) {
@ -134,7 +133,7 @@ public class PluginFactory implements ApplicationContextInitializer<Configurable
}
private static void addPlugin(String pluginName, File file) {
DefaultSystemLog.getLog().info("加载:{}插件", pluginName);
DefaultSystemLog.getLog().info("加载:{} 插件", pluginName);
ClassLoader contextClassLoader = ClassLoaderUtil.getClassLoader();
JarClassLoader.loadJar((URLClassLoader) contextClassLoader, file);
}
@ -144,51 +143,31 @@ public class PluginFactory implements ApplicationContextInitializer<Configurable
init();
// 扫描插件 实现
Set<Class<?>> classes = ClassUtil.scanPackage("io.jpom", IPlugin.class::isAssignableFrom);
List<PluginItem> pluginItems = classes.stream().filter(ClassUtil::isNormalClass).map(aClass -> {
PluginItem pluginItem = new PluginItem();
IPlugin plugin = (IPlugin) ReflectUtil.newInstance(aClass);
pluginItem.plugin = plugin;
pluginItem.name = plugin.name();
pluginItem.className = (Class<? extends IPlugin>) aClass;
return pluginItem;
}).collect(Collectors.toList());
List<PluginItemWrap> pluginItemWraps = classes
.stream()
.filter(aClass -> ClassUtil.isNormalClass(aClass) && aClass.isAnnotationPresent(PluginConfig.class))
.map(aClass -> new PluginItemWrap((Class<? extends IPlugin>) aClass))
.filter(pluginItemWrap -> {
if (StrUtil.isEmpty(pluginItemWrap.getName())) {
DefaultSystemLog.getLog().warn("plugin config name error:{}", pluginItemWrap.getClassName());
return false;
}
return true;
})
.collect(Collectors.toList());
//
Map<String, List<PluginItem>> pluginMap = CollStreamUtil.groupByKey(pluginItems, PluginItem::getName);
Map<String, List<PluginItemWrap>> pluginMap = CollStreamUtil.groupByKey(pluginItemWraps, PluginItemWrap::getName);
pluginMap.forEach((key, value) -> {
// 排序
value.sort((o1, o2) -> Comparator.comparingInt((ToIntFunction<PluginItem>) value1 -> value1.plugin.order()).compare(o1, o2));
value.sort((o1, o2) -> Comparator.comparingInt((ToIntFunction<PluginItemWrap>) value1 -> {
Order order = value1.getClassName().getAnnotation(Order.class);
if (order == null) {
return 0;
}
return order.value();
}).compare(o1, o2));
PLUGIN_MAP.put(key, value);
});
}
private static class PluginItem {
/**
* 插件名
*/
private String name;
/**
* 插件类名
*/
private Class<? extends IPlugin> className;
/**
* 插件对象
*/
private IPlugin plugin;
public String getName() {
return name;
}
public Class<? extends IPlugin> getClassName() {
return className;
}
public IPlugin getPlugin() {
return plugin;
}
}
}

View File

@ -0,0 +1,73 @@
package io.jpom.plugin;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.spring.SpringUtil;
/**
* 插件端对象
*
* @author bwcx_jzy
* @since 2021/12/24
*/
public class PluginItemWrap {
/**
* 配置相关
*/
private final PluginConfig pluginConfig;
/**
* 插件名
*/
private final String name;
/**
* 插件类名
*/
private final Class<? extends IPlugin> className;
/**
* 插件对象
*/
private volatile IPlugin plugin;
public PluginItemWrap(Class<? extends IPlugin> className) {
this.className = className;
this.pluginConfig = className.getAnnotation(PluginConfig.class);
if (StrUtil.isNotEmpty(this.pluginConfig.name())) {
this.name = this.pluginConfig.name();
} else {
this.name = this.pluginConfig.plugin().getName();
}
}
public PluginConfig getPluginConfig() {
return pluginConfig;
}
public String getName() {
return name;
}
public Class<? extends IPlugin> getClassName() {
return className;
}
public IPlugin getPlugin() {
if (plugin == null) {
synchronized (className) {
if (plugin == null) {
//
boolean nativeObject = this.pluginConfig.nativeObject();
if (nativeObject) {
plugin = ReflectUtil.newInstance(className);
} else {
plugin = SpringUtil.getBean(className);
}
}
}
}
return plugin;
}
}

View File

@ -29,6 +29,7 @@ import java.util.Map;
* @author bwcx_jzy
* @since 2021/12/24
*/
@PluginConfig(name = "charset-detector")
public class DefaultFileCharsetDetectorImpl implements IDefaultPlugin {
@Override
@ -36,9 +37,4 @@ public class DefaultFileCharsetDetectorImpl implements IDefaultPlugin {
File file = (File) main;
return new CharsetDetector().detectChineseCharset(file);
}
@Override
public String name() {
return "charset-detector";
}
}

View File

@ -29,6 +29,7 @@ import cn.jiangzeyin.common.DefaultSystemLog;
import com.alibaba.fastjson.JSONObject;
import io.jpom.plugin.DefaultPlugin;
import io.jpom.plugin.IDefaultPlugin;
import io.jpom.plugin.PluginConfig;
import javax.mail.Session;
import javax.mail.Transport;
@ -39,6 +40,7 @@ import java.util.Map;
* @author bwcx_jzy
* @since 2021/12/22
*/
@PluginConfig(plugin = DefaultPlugin.Email)
public class DefaultEmailPluginImpl implements IDefaultPlugin {
@Override
@ -107,9 +109,4 @@ public class DefaultEmailPluginImpl implements IDefaultPlugin {
mailAccount.setAuth(true);
return mailAccount;
}
@Override
public String name() {
return DefaultPlugin.Email.getName();
}
}

View File

@ -31,6 +31,7 @@ import java.util.Map;
* @author bwcx_jzy
* @since 2021/12/23
*/
@PluginConfig(plugin = DefaultPlugin.SvnClone)
public class DefaultSvnPluginImpl implements IDefaultPlugin {
@Override
@ -38,9 +39,4 @@ public class DefaultSvnPluginImpl implements IDefaultPlugin {
File savePath = (File) main;
return SvnKitUtil.checkOut(parameter, savePath);
}
@Override
public String name() {
return DefaultPlugin.SvnClone.getName();
}
}

View File

@ -29,6 +29,7 @@ import cn.hutool.http.HttpUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import io.jpom.plugin.DefaultPlugin;
import io.jpom.plugin.IDefaultPlugin;
import io.jpom.plugin.PluginConfig;
import java.util.Map;
@ -38,6 +39,7 @@ import java.util.Map;
* @author bwcx_jzy
* @since 2021/12/22
*/
@PluginConfig(plugin = DefaultPlugin.WebHook)
public class DefaultWebhookPluginImpl implements IDefaultPlugin {
@Override
@ -57,9 +59,4 @@ public class DefaultWebhookPluginImpl implements IDefaultPlugin {
return "WebHooks error:" + e.getMessage();
}
}
@Override
public String name() {
return DefaultPlugin.WebHook.getName();
}
}