Browse Source

KERNEL-6380 在部分插件切换的时候,需要有一个集中刷新缓存的地方

feature/big-screen
hades 4 years ago
parent
commit
9a157b8281
  1. 174
      designer-base/src/main/java/com/fr/base/ClassHelper.java
  2. 6
      designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java
  3. 11
      designer-base/src/test/java/com/fr/base/ClassHelperTest.java

174
designer-base/src/main/java/com/fr/base/ClassHelper.java

@ -1,174 +0,0 @@
package com.fr.base;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.jetbrains.annotations.Nullable;
/**
* @author hades
* @version 10.0
* Created by hades on 2020/12/28
*/
public class ClassHelper {
private static final Set<String> primClasses = new HashSet<>();
private static final Set<ClassLoader> classLoaders = new HashSet<>();
private static final Map<String, Field[]> map = new HashMap<>();
private static final Set<Object> data = new HashSet<>();
private static final String PLUGIN_CLASS_CLASSLOADER= "com.fr.plugin.engine.core.PluginClassLoader";
static {
primClasses.add("boolean");
primClasses.add("byte");
primClasses.add("char");
primClasses.add("short");
primClasses.add("int");
primClasses.add("long");
primClasses.add("float");
primClasses.add("double");
primClasses.add("void");
primClasses.add("java.lang.Boolean");
primClasses.add("java.lang.Byte");
primClasses.add("java.lang.Character");
primClasses.add("java.lang.Short");
primClasses.add("java.lang.Integer");
primClasses.add("java.lang.Long");
primClasses.add("java.lang.FLOAT");
primClasses.add("java.lang.DOUBLE");
primClasses.add("java.lang.Void");
primClasses.add("java.lang.String");
primClasses.add("java.awt.image.BufferedImage");
}
/**
* 获取当前对象字段中由插件加载出类的classloader
*
* @param o
* @return
*/
@Nullable
public static Set<ClassLoader> getPluginClassLoaders(Object o) {
try {
collectClassloader(o);
Set<ClassLoader> result = new HashSet<>(classLoaders);
data.clear();
classLoaders.clear();
map.clear();
return result;
} catch (Throwable e) {
FineLoggerFactory.getLogger().warn(e.getMessage(), e);
data.clear();
classLoaders.clear();
map.clear();
return null;
}
}
private static void collectClassloader(Object o) {
if (o == null) {
return;
}
Field[] fields;
Class<?> aclass = o.getClass();
String className = aclass.getName();
if (map.containsKey(className)) {
fields = map.get(className);
} else {
fields = fields(aclass, o);
map.put(className, fields);
}
if (aclass.isArray()) {
for (int i = 0, len = Array.getLength(o); i < len; i++) {
Object arrayOb = Array.get(o, i);
if (arrayOb != null) {
Class<?> arrayObClass = arrayOb.getClass();
String name = arrayObClass.getName();
if (primClasses.contains(name)) {
return;
}
data.add(arrayOb);
ClassLoader loader = arrayObClass.getClassLoader();
if (loader != null && ComparatorUtils.equals(loader.getClass().getName(), PLUGIN_CLASS_CLASSLOADER)) {
classLoaders.add(loader);
}
} else {
continue;
}
collectClassloader(arrayOb);
}
}
if (fields.length == 0) {
return;
}
for (Field field : fields) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
Object ob = null;
try {
ob = field.get(o);
if (ob == null) {
continue;
}
Class<?> clazz = ob.getClass();
String name = clazz.getName();
if (primClasses.contains(name)) {
continue;
}
if (!data.contains(ob)) {
data.add(ob);
ClassLoader loader = clazz.getClassLoader();
if (loader != null && ComparatorUtils.equals(loader.getClass().getName(), PLUGIN_CLASS_CLASSLOADER)) {
classLoaders.add(loader);
}
collectClassloader(ob);
}
} catch (Throwable e) {
FineLoggerFactory.getLogger().warn(e.getMessage(), e);
}
}
}
private static Field[] fields(Class<?> clazz, Object o) {
Class<?> t = clazz;
Set<Field> result = new HashSet<>();
do {
for (Field field : t.getDeclaredFields()) {
if (clazz != o ^ Modifier.isStatic(field.getModifiers())) {
result.add(field);
}
}
t = t.getSuperclass();
}
while (t != null);
return result.toArray(new Field[0]);
}
}

6
designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java

@ -1,6 +1,5 @@
package com.fr.design.file; package com.fr.design.file;
import com.fr.base.ClassHelper;
import com.fr.base.chart.chartdata.CallbackEvent; import com.fr.base.chart.chartdata.CallbackEvent;
import com.fr.base.io.BaseBook; import com.fr.base.io.BaseBook;
import com.fr.design.DesignerEnvManager; import com.fr.design.DesignerEnvManager;
@ -18,6 +17,7 @@ import com.fr.file.FILE;
import com.fr.file.FileNodeFILE; import com.fr.file.FileNodeFILE;
import com.fr.file.StashedFILE; import com.fr.file.StashedFILE;
import com.fr.general.ComparatorUtils; import com.fr.general.ComparatorUtils;
import com.fr.invoke.ClassHelper;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContext; import com.fr.plugin.context.PluginContext;
import com.fr.plugin.manage.PluginManager; import com.fr.plugin.manage.PluginManager;
@ -457,7 +457,7 @@ public class HistoryTemplateListCache implements CallbackEvent {
} }
templateNeedReloadMap.clear(); templateNeedReloadMap.clear();
FineLoggerFactory.getLogger().info("Plugin env change reload all template ended"); FineLoggerFactory.getLogger().info("Plugin env change reload all template ended");
FineLoggerFactory.getLogger().debug("Reload all template spend: {} ms", (System.currentTimeMillis() - start)); FineLoggerFactory.getLogger().info("Reload all template spend: {} ms", (System.currentTimeMillis() - start));
} }
public void calNeedReloadTemplate(PluginContext context) { public void calNeedReloadTemplate(PluginContext context) {
@ -466,7 +466,7 @@ public class HistoryTemplateListCache implements CallbackEvent {
if (baseBook != null) { if (baseBook != null) {
String name = template.getEditingFILE().getName(); String name = template.getEditingFILE().getName();
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
Set<ClassLoader> set = ClassHelper.getPluginClassLoaders(baseBook); Set<ClassLoader> set = ClassHelper.getClassLoaders(baseBook);
FineLoggerFactory.getLogger().info("{} find plugin classloader spend: {} ms", name, (System.currentTimeMillis() - start)); FineLoggerFactory.getLogger().info("{} find plugin classloader spend: {} ms", name, (System.currentTimeMillis() - start));
if (set != null) { if (set != null) {
for (ClassLoader classLoader : set) { for (ClassLoader classLoader : set) {

11
designer-base/src/test/java/com/fr/base/ClassHelperTest.java

@ -1,6 +1,7 @@
package com.fr.base; package com.fr.base;
import com.fr.form.main.Form; import com.fr.form.main.Form;
import com.fr.invoke.ClassHelper;
import com.fr.main.impl.WorkBook; import com.fr.main.impl.WorkBook;
import java.util.Set; import java.util.Set;
import junit.framework.TestCase; import junit.framework.TestCase;
@ -15,13 +16,13 @@ import org.junit.Assert;
public class ClassHelperTest extends TestCase { public class ClassHelperTest extends TestCase {
public void testGetPluginClassLoaders() { public void testGetClassLoaders() {
WorkBook workBook = new WorkBook(); WorkBook workBook = new WorkBook();
Set<ClassLoader> set = ClassHelper.getPluginClassLoaders(workBook); Set<ClassLoader> set = ClassHelper.getClassLoaders(workBook);
Assert.assertEquals(0, set.size()); Assert.assertFalse(set.isEmpty());
Form form = new Form(); Form form = new Form();
Set<ClassLoader> set1 = ClassHelper.getPluginClassLoaders(form); Set<ClassLoader> set1 = ClassHelper.getClassLoaders(form);
Assert.assertEquals(0, set1.size()); Assert.assertFalse(set1.isEmpty());
} }

Loading…
Cancel
Save