0

我想将运行时反射与 Scala 注释一起使用(如果需要,也可以是 Java 注释,但我更愿意限制纯 Java 代码)

我想实现类似的东西:

/**
  print all methods that implement a specific annotation
*/
 def getAllAnnotated(): Unit {...}

例如,如果我有:

class Foo {
    @printme
    def foo(args: A): R
    
    def oof(args: A): R
}
class Bar {
    @printme
    def bar(): Unit
}

运行的结果getAllAnnotated()是这样的:

Foo.foo
Bar.bar

请注意,我不想查看特定的类,而是查看任何可用的方法

4

2 回答 2

2

尝试基于 Java 反射(例如Reflections)+ scala-reflect的类路径扫描器之一。由于我们只使用 Java 反射来查找类,而使用 scala-reflect 来查找带注释的方法,因此可以在 Scala 中编写注释。

import org.reflections.Reflections
import org.reflections.scanners.SubTypesScanner
import org.reflections.util.{ClasspathHelper, ConfigurationBuilder}
import scala.annotation.StaticAnnotation
import scala.jdk.CollectionConverters._
import scala.reflect.runtime.currentMirror
import scala.reflect.runtime.universe._

class printme extends StaticAnnotation

val reflections = new Reflections(
  (new ConfigurationBuilder)
    .setUrls(ClasspathHelper.forPackage(""))
    .setScanners(new SubTypesScanner(false))
)

def getAllAnnotated(): Unit =
  reflections.getAllTypes.asScala
    .flatMap(className =>
      currentMirror.classSymbol(Class.forName(className))
        .toType
        .decls
        .filter(symbol =>
          symbol.isMethod && symbol.annotations.exists(_.tree.tpe =:= typeOf[printme])
        )
        .map(method => s"$className.${method.name}")
    ).foreach(println)

Reflections 库的替代品有ClassGraphBurningwave。如果我们将 scala-reflect 替换为 Java 反射,那么注释将必须用 Java 编写,因为只有用 Java 编写的注释在运行时通过 Java 反射可见。

于 2020-09-25T20:28:12.713 回答
1

在 Java 中,您可以使用反射使用反射扫描包中的类以获取包的所有类,然后递归地进入所有类以查找注释。

于 2020-09-25T19:14:18.023 回答