spring-boot-dependencies里已经申明了janino的版本,spring-boot项目直接引入依赖即可
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
</dependency>
// 使用spring boot的LaunchedURLClassLoader作为上级classLoader
JavaSourceClassLoader classloader = new JavaSourceClassLoader(this.getClass().getClassLoader());
把classloader作为局部变量及时释放,可以在old gc时,回收metaspace里的无用class定义
// 编译
String className = "mypackage.B";
String source = """
package mypackage;
import org.slf4j.*;
public class B implements Runnable {
Logger log = LoggerFactory.getLogger(this.getClass());
public void run() {
log.info("HELLO AAA from {}", this.getClass().getCanonicalName());
}
}
""";
MapResourceFinder map = new MapResourceFinder();
map.addResource(className.replace(".", "/") + ".java", source);
classloader.setSourceFinder(map);
Class<?> dynamicClass = classloader.loadClass(className);
// 运行
Runnable runnable = (Runnable) dynamicClass.getDeclaredConstructor().newInstance();
runnable.run();