feat: 修改classloader

This commit is contained in:
wangyu 2021-01-15 11:33:54 +08:00
parent 18c3d327d7
commit ee334b4cd5
6 changed files with 97 additions and 89 deletions

View File

@ -0,0 +1,15 @@
package com.flyfish.framework.compiler.core;
/**
* 静态访问器
*
* @author wangyu
*/
public interface ClassLoaders {
MemoryClassLoader CLASS_LOADER = new MemoryClassLoader();
static MemoryClassLoader memory() {
return CLASS_LOADER;
}
}

View File

@ -20,11 +20,11 @@ public class JavaStringCompiler implements Closeable {
private final MemoryJavaFileManager manager; private final MemoryJavaFileManager manager;
private final MemoryClassLoader classLoader; private final MemoryClassLoader classLoader;
public JavaStringCompiler() { public JavaStringCompiler(MemoryClassLoader classLoader) {
this.compiler = ToolProvider.getSystemJavaCompiler(); this.compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager stdManager = compiler.getStandardFileManager(null, null, null); StandardJavaFileManager stdManager = compiler.getStandardFileManager(null, null, null);
this.manager = new MemoryJavaFileManager(stdManager); this.manager = new MemoryJavaFileManager(stdManager, classLoader);
this.classLoader = new MemoryClassLoader(manager.getClassBytes()); this.classLoader = classLoader;
} }
/** /**
@ -57,15 +57,6 @@ public class JavaStringCompiler implements Closeable {
return classLoader.loadClass(name); return classLoader.loadClass(name);
} }
/**
* get the classLoader
*
* @return 结果
*/
public ClassLoader getClassLoader() {
return classLoader;
}
@Override @Override
public void close() { public void close() {
try { try {

View File

@ -3,6 +3,7 @@ package com.flyfish.framework.compiler.core;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* Load class from byte[] which is compiled in memory. * Load class from byte[] which is compiled in memory.
@ -12,11 +13,10 @@ import java.util.Map;
class MemoryClassLoader extends URLClassLoader { class MemoryClassLoader extends URLClassLoader {
// class name to class bytes: // class name to class bytes:
private final Map<String, byte[]> classBytes; private final Map<String, byte[]> classBytes = new ConcurrentHashMap<>();
public MemoryClassLoader(Map<String, byte[]> classBytes) { public MemoryClassLoader() {
super(new URL[0], MemoryClassLoader.class.getClassLoader()); super(new URL[0], MemoryClassLoader.class.getClassLoader());
this.classBytes = classBytes;
} }
@Override @Override
@ -29,4 +29,7 @@ class MemoryClassLoader extends URLClassLoader {
return defineClass(name, buf, 0, buf.length); return defineClass(name, buf, 0, buf.length);
} }
public Map<String, byte[]> getClassBytes() {
return classBytes;
}
} }

View File

@ -19,10 +19,11 @@ import java.util.concurrent.ConcurrentHashMap;
class MemoryJavaFileManager extends ForwardingJavaFileManager<JavaFileManager> { class MemoryJavaFileManager extends ForwardingJavaFileManager<JavaFileManager> {
// compiled classes in bytes: // compiled classes in bytes:
final Map<String, byte[]> classBytes = new ConcurrentHashMap<>(); private final Map<String, byte[]> classBytes;
MemoryJavaFileManager(JavaFileManager fileManager) { MemoryJavaFileManager(JavaFileManager fileManager, MemoryClassLoader classLoader) {
super(fileManager); super(fileManager);
classBytes = classLoader.getClassBytes();
} }
public Map<String, byte[]> getClassBytes() { public Map<String, byte[]> getClassBytes() {

View File

@ -1,12 +1,10 @@
package com.flyfish.framework.compiler.support; package com.flyfish.framework.compiler.support;
import com.flyfish.framework.compiler.DynamicJavaCompiler; import com.flyfish.framework.compiler.DynamicJavaCompiler;
import com.flyfish.framework.compiler.core.ClassLoaders;
import com.flyfish.framework.compiler.core.JavaStringCompiler; import com.flyfish.framework.compiler.core.JavaStringCompiler;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.util.StreamUtils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map; import java.util.Map;
/** /**
@ -17,7 +15,7 @@ import java.util.Map;
public class DelegateJavaCompiler implements DynamicJavaCompiler { public class DelegateJavaCompiler implements DynamicJavaCompiler {
// 第三方编译器 // 第三方编译器
private final JavaStringCompiler compiler = new JavaStringCompiler(); private final JavaStringCompiler compiler = new JavaStringCompiler(ClassLoaders.memory());
private DelegateJavaCompiler() { private DelegateJavaCompiler() {
} }
@ -27,7 +25,7 @@ public class DelegateJavaCompiler implements DynamicJavaCompiler {
} }
public static ClassLoader classLoader() { public static ClassLoader classLoader() {
return getInstance().compiler.getClassLoader(); return ClassLoaders.memory();
} }
/** /**
@ -54,17 +52,16 @@ public class DelegateJavaCompiler implements DynamicJavaCompiler {
compiler.close(); compiler.close();
} }
private static class SingletonHolder { private static class SingletonHolder {
private static final DelegateJavaCompiler INSTANCE = new DelegateJavaCompiler(); private static final DelegateJavaCompiler INSTANCE = new DelegateJavaCompiler();
} }
public static void main(String[] args) throws ClassNotFoundException, IOException { // public static void main(String[] args) throws ClassNotFoundException, IOException {
long time = System.currentTimeMillis(); // long time = System.currentTimeMillis();
System.out.println(StreamUtils.copyToString(DelegateJavaCompiler.class.getResourceAsStream("./"), StandardCharsets.UTF_8)); // System.out.println(StreamUtils.copyToString(DelegateJavaCompiler.class.getResourceAsStream("./"), StandardCharsets.UTF_8));
Class<?> clazz = getInstance().compile("Fuck.java", "package com.flyfish.project; public class Fuck {}"); // Class<?> clazz = getInstance().compile("Fuck.java", "package com.flyfish.project; public class Fuck {}");
System.out.println(clazz + "耗时:" + (System.currentTimeMillis() - time) / 1000.0 + ""); // System.out.println(clazz + "耗时:" + (System.currentTimeMillis() - time) / 1000.0 + "");
} // }
} }

View File

@ -1,6 +1,7 @@
package com.flyfish.framework.boot; package com.flyfish.framework.boot;
import com.flyfish.framework.compiler.core.ClassLoaders;
import com.flyfish.framework.compiler.support.DelegateJavaCompiler; import com.flyfish.framework.compiler.support.DelegateJavaCompiler;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
@ -14,7 +15,7 @@ import org.springframework.context.ConfigurableApplicationContext;
public class FlyfishAppRunner { public class FlyfishAppRunner {
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) { public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
Thread.currentThread().setContextClassLoader(DelegateJavaCompiler.classLoader()); Thread.currentThread().setContextClassLoader(ClassLoaders.memory());
return SpringApplication.run(new Class[]{primarySource}, args); return SpringApplication.run(new Class[]{primarySource}, args);
} }