mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-02 11:58:01 +08:00
插件加载调整
This commit is contained in:
parent
54fe8003da
commit
bcf75e8f9c
@ -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
|
||||
*/
|
||||
|
@ -30,13 +30,4 @@ package io.jpom.plugin;
|
||||
*/
|
||||
public interface IDefaultPlugin extends IPlugin {
|
||||
|
||||
/**
|
||||
* 默认插件排序到最后
|
||||
*
|
||||
* @return max
|
||||
*/
|
||||
@Override
|
||||
default int order() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user