[Change] Core 调整 Context 内部对象的传递方式;

[Add] CloneableFrameworkContext 添加可克隆 Context 抽象类;
[Change] DefaultFrameworkContext 更改实现为继承 CloneableFrameworkContext 以允许克隆 Context;
[Change] FrameworkManager, FrameworkFactory 更改 Context 内部对象的传递方式, 改用 CloneableFrameworkContext 进行传递;
This commit is contained in:
LamGC 2020-11-28 11:29:31 +08:00
parent 67510aa305
commit 7d0124418f
Signed by: LamGC
GPG Key ID: 6C5AE2A913941E1D
4 changed files with 64 additions and 20 deletions

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.framework;
/**
* 可克隆的 Context.
* @author LamGC
*/
public abstract class CloneableFrameworkContext implements FrameworkContext {
/**
* 克隆一个成员对象相同的全新 Context.
* @return 返回新的 FrameworkContext, Context 不能与当前 Context 相同对象.
*/
protected abstract FrameworkContext cloneContext();
}

View File

@ -24,7 +24,7 @@ import net.lamgc.cgj.bot.event.EventExecutor;
* 框架上下文的默认实现. * 框架上下文的默认实现.
* @author LamGC * @author LamGC
*/ */
class DefaultFrameworkContext implements FrameworkContext { class DefaultFrameworkContext extends CloneableFrameworkContext {
private final EventExecutor eventExecutor; private final EventExecutor eventExecutor;
private final CacheStoreBuilder cacheStoreBuilder; private final CacheStoreBuilder cacheStoreBuilder;
@ -44,4 +44,9 @@ class DefaultFrameworkContext implements FrameworkContext {
public CacheStoreBuilder getCacheStoreBuilder() { public CacheStoreBuilder getCacheStoreBuilder() {
return cacheStoreBuilder; return cacheStoreBuilder;
} }
@Override
protected FrameworkContext cloneContext() {
return new DefaultFrameworkContext(this.eventExecutor, this.cacheStoreBuilder);
}
} }

View File

@ -17,8 +17,6 @@
package net.lamgc.cgj.bot.framework; 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.Plugin;
import org.pf4j.PluginFactory; import org.pf4j.PluginFactory;
import org.pf4j.PluginWrapper; import org.pf4j.PluginWrapper;
@ -28,6 +26,7 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.Objects;
/** /**
* 经过调整的, 针对 Framework 的实例工厂类. * 经过调整的, 针对 Framework 的实例工厂类.
@ -38,16 +37,14 @@ final class FrameworkFactory implements PluginFactory {
private final static Logger log = LoggerFactory.getLogger(FrameworkFactory.class); private final static Logger log = LoggerFactory.getLogger(FrameworkFactory.class);
private final File dataRootFolder; private final File dataRootFolder;
private final CacheStoreBuilder cacheStoreBuilder; private final CloneableFrameworkContext parentContext;
private final EventExecutor eventExecutor;
public FrameworkFactory(File dataRootFolder, CacheStoreBuilder cacheStoreBuilder, EventExecutor eventExecutor) { public FrameworkFactory(File dataRootFolder, CloneableFrameworkContext context) {
this.dataRootFolder = dataRootFolder; this.dataRootFolder = Objects.requireNonNull(dataRootFolder);
this.cacheStoreBuilder = cacheStoreBuilder;
this.eventExecutor = eventExecutor;
if (!this.dataRootFolder.exists() && !this.dataRootFolder.mkdirs()) { if (!this.dataRootFolder.exists() && !this.dataRootFolder.mkdirs()) {
log.warn("框架数据目录创建异常, 可能会导致后续框架存取数据失败!"); log.warn("框架数据目录创建异常, 可能会导致后续框架存取数据失败!");
} }
this.parentContext = Objects.requireNonNull(context);
} }
@Override @Override
@ -81,7 +78,7 @@ final class FrameworkFactory implements PluginFactory {
.getConstructor(PluginWrapper.class, File.class, FrameworkContext.class); .getConstructor(PluginWrapper.class, File.class, FrameworkContext.class);
Framework instance = (Framework) constructor.newInstance(pluginWrapper, Framework instance = (Framework) constructor.newInstance(pluginWrapper,
new File(dataRootFolder, pluginWrapper.getPluginId()), new File(dataRootFolder, pluginWrapper.getPluginId()),
new DefaultFrameworkContext(eventExecutor, cacheStoreBuilder)); parentContext.cloneContext());
try { try {
instance.initial(); instance.initial();
} catch (Throwable e) { } catch (Throwable e) {

View File

@ -17,12 +17,11 @@
package net.lamgc.cgj.bot.framework; package net.lamgc.cgj.bot.framework;
import net.lamgc.cgj.bot.cache.CacheStoreBuilder;
import net.lamgc.cgj.bot.event.EventExecutor;
import org.pf4j.*; import org.pf4j.*;
import java.io.File; import java.io.File;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Objects;
/** /**
* 框架管理器. * 框架管理器.
@ -30,15 +29,27 @@ import java.nio.file.Path;
*/ */
public class FrameworkManager extends JarPluginManager { public class FrameworkManager extends JarPluginManager {
private final CacheStoreBuilder cacheStoreBuilder; private final boolean initialed;
private final EventExecutor eventExecutor; private final CloneableFrameworkContext parentContext;
public FrameworkManager(String systemVersion, File frameworksDirectory, public FrameworkManager(String systemVersion, File frameworksDirectory, CloneableFrameworkContext context) {
CacheStoreBuilder cacheStoreBuilder, EventExecutor eventExecutor) {
super(frameworksDirectory.toPath()); super(frameworksDirectory.toPath());
this.cacheStoreBuilder = cacheStoreBuilder;
this.eventExecutor = eventExecutor;
setSystemVersion(systemVersion); 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 @Override
@ -69,7 +80,6 @@ public class FrameworkManager extends JarPluginManager {
@Override @Override
protected PluginFactory createPluginFactory() { protected PluginFactory createPluginFactory() {
return new FrameworkFactory(getPluginsRoot().getParent().resolve("frameworkData").toFile(), return new FrameworkFactory(getPluginsRoot().getParent().resolve("frameworkData").toFile(), parentContext);
cacheStoreBuilder, eventExecutor);
} }
} }