请注意:此问题是关于如何在 Scala 中完成类路径扫描(通过反射),而不是Java。我在这个网站上的任何地方都没有看到这个问题,因此我不相信这是一个重复的问题。
我有一个Scala项目目录结构,如下所示:
myapp/
src/main/scala/
com/
me/
myapp/
messages/
BaseMessage.scala
FizzMessage.scala
utils
<omitted for brevity>
logging
<omitted for brevity>
driver
<omitted for brevity>
注意messages
包。目前它只在其中定义了两个类,BaseMessage
(抽象基类)和FizzMessage
(扩展BaseMessage
)。但最终它将包含数百个其他所有BaseMessage
子类的类。
在我的代码中,我有以下内容:
deviceManager.registerMessage(new FizzMessage())
随着时间的推移,我向BaseMessage
包中添加了数十个,可能是数百个messages
子类,我将不得不添加一行代码来注册&#34;注册&#34;每种新的消息类型。随后,如果我重构或删除消息,我将不得不记得从上面删除他们各自的注册码。这将很难管理,我想知道我是否可以使用反射来扫描messages
包裹中的BaseMessage
impls,然后注册它们:
val messageImpls : Array[T > BaseMessage] = getViaReflection("com.me.myapp.messages")
messageImpls.foreach { msgImpl =>
deviceManager.registerMessage(msgImpl)
}
关于如何实现这一目标的任何想法?
答案 0 :(得分:0)
如果您可以使用getResources
访问感兴趣的类,则可以过滤这些结果,甚至递归子目录(此处未显示):
def getClasses(packageName: String) = {
val classLoader = getClass.getClassLoader
val path = packageName.replace('.', '/')
val resources: util.Enumeration[URL] = classLoader.getResources(path)
Iterator.continually((resources, resources.nextElement))
.takeWhile(_._1.hasMoreElements)
.map{ case (_, resource: URL) =>
new File(resource.getFile)
.listFiles
.withFilter(_.getName.endsWith(".class"))
.map{ file =>
Class.forName(packageName + '.' + file.getName.dropRight(6))
}
}
}