簡體   English   中英

如何在運行時在 Scala/Java 中找到帶注釋的方法

[英]How can I find Annotated methods in Scala/Java on Runtime

我想使用帶有 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

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

嘗試一種基於 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)

反射庫的替代品是例如ClassGraphBurningwave 如果我們將 scala-reflect 替換為 Java 反射,那么注釋將必須用 Java 編寫,因為只有用 Java 編寫的注釋在運行時通過 Java 反射可見。

在 Java 中,您可以使用反射掃描包中的類使用反射來獲取包的所有類,然后遞歸地進入所有類以查找注釋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM