[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
*/
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);
}
}

View File

@ -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) {

View File

@ -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);
}
}