使用反射在 Kotlin 中获取带注释函数列表

3

我刚接触Kotlin,我想要做以下几件事:

  1. 使用注解(例如"Executable")注释一些函数

  2. 在运行时获取所有带有该注解的函数

  3. 检查注解上的属性,如果满足条件,则调用函数

我有以下代码:

annotation class Executable(val name : String)

@Executable("doSomething")
fun stepDoSomething (param1 : String) {
    println("I am a step that does something! I print $param1")
}

然而,我不清楚如何在运行时检索所有具有可执行注释的函数并对它们进行检查。

谢谢你的帮助!

2个回答

2
为了实现这一点,您需要使用类路径扫描器,例如ClassGraph。类路径扫描器提供API,以基于各种标准查找类,例如它们所在的包,它们实现的接口或它们拥有的注释。在ClassGraph的情况下,ScanResult具有getClassesWithMethodAnnotation(String name)方法。一旦您拥有了所有这些类,就可以使用普通反射来查找这些类中具有特定注释的方法,并检查注释的属性。这里是如何创建注释并使用反射检查它的良好概述。

非常感谢!我能够通过那个让它工作。 - user12276369

2

这是我基于(非常有帮助的)Matthew Pope的答案实现的:

import io.github.classgraph.ClassGraph
import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.jvm.kotlinFunction

@Image(filename = "image-1.svg")
fun foo() {
    println("in foo")
}

@Image(filename = "image-2.svg")
fun bar() {
    println("in bar")
}

@Throws(Exception::class)
fun getAllAnnotatedWith(annotation: KClass<out Annotation>): List<KFunction<*>> {
    val `package` = annotation.java.`package`.name
    val annotationName = annotation.java.canonicalName

    return ClassGraph()
        .enableAllInfo()
        .acceptPackages(`package`)
        .scan().use { scanResult ->
            scanResult.getClassesWithMethodAnnotation(annotationName).flatMap { routeClassInfo ->
                routeClassInfo.methodInfo.filter{ function ->
                     function.hasAnnotation(annotation.java) }.mapNotNull { method ->
                        method.loadClassAndGetMethod().kotlinFunction
                        // if parameter needed:
                        // method.getAnnotationInfo(routeAnnotation).parameterValues.map { it.value }
                    }
            }
        }
}

fun main(args: Array<String>) {
    getAllAnnotatedWith(Image::class)
        .forEach { function ->
            function.call()
        }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接