英文:
How can I find Annotated methods in Scala/Java on Runtime
问题
我想要使用运行时反射与Scala注解(如果必要的话也可以是Java注解,但我更倾向于限制纯Java代码)。
我想要实现类似于:
/**
打印所有带有特定注解的方法
*/
def getAllAnnotated(): Unit {...}
例如,如果我有:
```scala
class Foo {
@printme
def foo(args: A): R
def oof(args: A): R
}
class Bar {
@printme
def bar(): Unit
}
运行 getAllAnnotated()
的结果可能是:
Foo.foo
Bar.bar
请注意,我不想查找特定的类,而是查找任何可用的方法。
<details>
<summary>英文:</summary>
I want to use Runtime Reflection with Scala annotations (could also be a Java annoations if necessary, but I would prefer to limit pure Java code)
I want to implement something like:
/**
print all methods that implement a specific annotation
*/
def getAllAnnotated(): Unit {...}
For example, if I have:
class Foo {
@printme
def foo(args: A): R
def oof(args: A): R
}
class Bar {
@printme
def bar(): Unit
}
The result of running `getAllAnnotated()` would be something like:
Foo.foo
Bar.bar
Note that I don't want to look in a specific class, but instead any available method
</details>
# 答案1
**得分**: 2
尝试使用基于Java反射的类路径扫描器之一(例如[Reflections][1]) + [scala-reflect][2]。由于我们仅使用Java反射来查找类,并使用scala-reflect来查找带注释的方法,因此注释可以用Scala编写。
```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库的替代方案包括ClassGraph和Burningwave。如果我们用Java反射替换scala-reflect,那么注释必须用Java编写,因为只有使用Java编写的注释在运行时才能通过Java反射可见。
英文:
Try one of classpath scanners based on Java reflection (e.g. Reflections) + scala-reflect. Since we use Java reflection only to look for classes and scala-reflect to look for annotated methods, annotations can be written in 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)
Alternatives to Reflections library are for example ClassGraph and Burningwave. If we replace scala-reflect with Java reflection then annotation will have to be written in Java because only annotations written in Java are visible at runtime with Java reflection.
答案2
得分: 1
在Java中,您可以使用反射来扫描包中的类。使用Reflections来获取包中的所有类,然后递归地进入所有类以查找注解。
英文:
In Java you can scan for the classes in the package using reflection Using Reflections to get all classes of the package and then recursively go inside all the classes to find the annotations.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论