From 7d0124418f688dac332e361ae48fe6119a0590dd Mon Sep 17 00:00:00 2001 From: LamGC Date: Sat, 28 Nov 2020 11:29:31 +0800 Subject: [PATCH] =?UTF-8?q?[Change]=20Core=20=E8=B0=83=E6=95=B4=20Context?= =?UTF-8?q?=20=E5=86=85=E9=83=A8=E5=AF=B9=E8=B1=A1=E7=9A=84=E4=BC=A0?= =?UTF-8?q?=E9=80=92=E6=96=B9=E5=BC=8F;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Add] CloneableFrameworkContext 添加可克隆 Context 抽象类; [Change] DefaultFrameworkContext 更改实现为继承 CloneableFrameworkContext 以允许克隆 Context; [Change] FrameworkManager, FrameworkFactory 更改 Context 内部对象的传递方式, 改用 CloneableFrameworkContext 进行传递; --- .../framework/CloneableFrameworkContext.java | 32 +++++++++++++++++++ .../framework/DefaultFrameworkContext.java | 7 +++- .../cgj/bot/framework/FrameworkFactory.java | 15 ++++----- .../cgj/bot/framework/FrameworkManager.java | 30 +++++++++++------ 4 files changed, 64 insertions(+), 20 deletions(-) create mode 100644 ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/CloneableFrameworkContext.java diff --git a/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/CloneableFrameworkContext.java b/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/CloneableFrameworkContext.java new file mode 100644 index 0000000..e52714a --- /dev/null +++ b/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/CloneableFrameworkContext.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 LamGC + * + * ContentGrabbingJi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * ContentGrabbingJi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package net.lamgc.cgj.bot.framework; + +/** + * 可克隆的 Context. + * @author LamGC + */ +public abstract class CloneableFrameworkContext implements FrameworkContext { + + /** + * 克隆一个成员对象相同的全新 Context. + * @return 返回新的 FrameworkContext, 该 Context 不能与当前 Context 相同对象. + */ + protected abstract FrameworkContext cloneContext(); + +} diff --git a/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/DefaultFrameworkContext.java b/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/DefaultFrameworkContext.java index d97996c..486ffb4 100644 --- a/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/DefaultFrameworkContext.java +++ b/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/DefaultFrameworkContext.java @@ -24,7 +24,7 @@ import net.lamgc.cgj.bot.event.EventExecutor; * 框架上下文的默认实现. * @author LamGC */ -class DefaultFrameworkContext implements FrameworkContext { +class DefaultFrameworkContext extends CloneableFrameworkContext { private final EventExecutor eventExecutor; private final CacheStoreBuilder cacheStoreBuilder; @@ -44,4 +44,9 @@ class DefaultFrameworkContext implements FrameworkContext { public CacheStoreBuilder getCacheStoreBuilder() { return cacheStoreBuilder; } + + @Override + protected FrameworkContext cloneContext() { + return new DefaultFrameworkContext(this.eventExecutor, this.cacheStoreBuilder); + } } diff --git a/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/FrameworkFactory.java b/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/FrameworkFactory.java index 0b3922e..d3f3deb 100644 --- a/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/FrameworkFactory.java +++ b/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/FrameworkFactory.java @@ -17,8 +17,6 @@ package net.lamgc.cgj.bot.framework; -import net.lamgc.cgj.bot.cache.CacheStoreBuilder; -import net.lamgc.cgj.bot.event.EventExecutor; import org.pf4j.Plugin; import org.pf4j.PluginFactory; import org.pf4j.PluginWrapper; @@ -28,6 +26,7 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; +import java.util.Objects; /** * 经过调整的, 针对 Framework 的实例工厂类. @@ -38,16 +37,14 @@ final class FrameworkFactory implements PluginFactory { private final static Logger log = LoggerFactory.getLogger(FrameworkFactory.class); private final File dataRootFolder; - private final CacheStoreBuilder cacheStoreBuilder; - private final EventExecutor eventExecutor; + private final CloneableFrameworkContext parentContext; - public FrameworkFactory(File dataRootFolder, CacheStoreBuilder cacheStoreBuilder, EventExecutor eventExecutor) { - this.dataRootFolder = dataRootFolder; - this.cacheStoreBuilder = cacheStoreBuilder; - this.eventExecutor = eventExecutor; + public FrameworkFactory(File dataRootFolder, CloneableFrameworkContext context) { + this.dataRootFolder = Objects.requireNonNull(dataRootFolder); if (!this.dataRootFolder.exists() && !this.dataRootFolder.mkdirs()) { log.warn("框架数据目录创建异常, 可能会导致后续框架存取数据失败!"); } + this.parentContext = Objects.requireNonNull(context); } @Override @@ -81,7 +78,7 @@ final class FrameworkFactory implements PluginFactory { .getConstructor(PluginWrapper.class, File.class, FrameworkContext.class); Framework instance = (Framework) constructor.newInstance(pluginWrapper, new File(dataRootFolder, pluginWrapper.getPluginId()), - new DefaultFrameworkContext(eventExecutor, cacheStoreBuilder)); + parentContext.cloneContext()); try { instance.initial(); } catch (Throwable e) { diff --git a/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/FrameworkManager.java b/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/FrameworkManager.java index 23d087a..df2914c 100644 --- a/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/FrameworkManager.java +++ b/ContentGrabbingJi-core/src/main/java/net/lamgc/cgj/bot/framework/FrameworkManager.java @@ -17,12 +17,11 @@ package net.lamgc.cgj.bot.framework; -import net.lamgc.cgj.bot.cache.CacheStoreBuilder; -import net.lamgc.cgj.bot.event.EventExecutor; import org.pf4j.*; import java.io.File; import java.nio.file.Path; +import java.util.Objects; /** * 框架管理器. @@ -30,15 +29,27 @@ import java.nio.file.Path; */ public class FrameworkManager extends JarPluginManager { - private final CacheStoreBuilder cacheStoreBuilder; - private final EventExecutor eventExecutor; + private final boolean initialed; + private final CloneableFrameworkContext parentContext; - public FrameworkManager(String systemVersion, File frameworksDirectory, - CacheStoreBuilder cacheStoreBuilder, EventExecutor eventExecutor) { + public FrameworkManager(String systemVersion, File frameworksDirectory, CloneableFrameworkContext context) { super(frameworksDirectory.toPath()); - this.cacheStoreBuilder = cacheStoreBuilder; - this.eventExecutor = eventExecutor; setSystemVersion(systemVersion); + this.parentContext = Objects.requireNonNull(context); + + // 在 super() 中会调用一次 initialize(), 但此时 FrameworkManager 内的成员变量尚未初始化, + // 此时 super.initialize() 调用到 FrameworkManager 中的 createPluginFactory 时, context 传递为 null + // 导致 FrameworkFactory 抛出 NPE, 故覆写 initialize() 阻止 super() 过早调用 initialize(). + initialed = true; + initialize(); + } + + @Override + protected void initialize() { + if (!initialed) { + return; + } + super.initialize(); } @Override @@ -69,7 +80,6 @@ public class FrameworkManager extends JarPluginManager { @Override protected PluginFactory createPluginFactory() { - return new FrameworkFactory(getPluginsRoot().getParent().resolve("frameworkData").toFile(), - cacheStoreBuilder, eventExecutor); + return new FrameworkFactory(getPluginsRoot().getParent().resolve("frameworkData").toFile(), parentContext); } }