我正在构建一个使用插件架构的应用程序Scala,并尝试在运行时加载插件。目前,我的插件加载程序代码是:
import org.clapper.classutil.ClassFinder
object PluginManager extends PluginManager {
val plugins = new mutable.HashMap[String, Plugin]()
val pluginFolder = new File("plugins")
def init(): Unit = {
val pluginJars = pluginFolder.listFiles.filter(_.getName.endsWith(".jar"))
val classpath = List(new File(".")) ++ pluginJars
val finder = ClassFinder(classpath)
val classes = finder.getClasses()
val classMap = ClassFinder.classInfoMap(classes.iterator)
val pluginsToLoad = ClassFinder.concreteSubclasses("org.narrativeandplay.hypedyn.plugins.Plugin", classMap)
val loader = new URLClassLoader(pluginJars.map({ f => new URL(s"file:${f.getAbsolutePath}") }), ClassLoader.getSystemClassLoader)
pluginsToLoad.foreach {
pluginString =>
val plugin = loader.loadClass(pluginString.name).newInstance().asInstanceOf[Plugin]
plugins += plugin.name -> plugin
}
}
}
(基于https://vikashazrati.wordpress.com/2011/09/15/building-a-plugin-based-architecture-in-scala/)。
我不得不使用URLClassLoader
,因为当应用程序启动时,我的插件JAR不在类路径上
我想知道是否可以使用Scala Reflection API来代替我对URLClassLoader
的使用,如果可以,我应该怎么做?
为了让Scala反射API的运行时反射部分工作,您无论如何都需要实例化一个类加载器(然后执行scala.reflect.runtime.universe.runtimeMirror(classloader)
),所以我认为在这种情况下它不会简化问题。