cpe
09/19/2022, 8:05 AMcompanion object
. So I decided to provide an interface (or an annotation) and find the functions to call on startup as follows using (using classgraph as for scanning - I’m not bound to that framework):
interface OnStartup {
fun onStartup()
}
// a class that wil instantiated a lot of times during runtime
data class SomeClass(val name: String) {
companion object : OnStartup {
override fun onStartup() {
// notify someone at startup about our existence
}
}
}
fun main() {
ClassGraph().enableAllInfo().acceptPackages("com.test").scan()
.getClassesImplementing(OnStartup::class.java)
.filter { it.isStatic }
.flatMap { findStartupMethods(it) }
.forEach {
it.call()
}
}
private fun findStartupMethods(classInfo: ClassInfo): List<KFunction<*>> {
return classInfo.methodInfo.filter { function ->
function.name == "onStartup"
}.mapNotNull { method ->
method.loadClassAndGetMethod().kotlinFunction
}
}
This will not work as call()
expects a parameter: Callable expects 1 arguments, but 0 were provided.
which should be the instance of the class (from my understanding), so I guess it should be the companionObjectReference
. The code works well if I define the onStartup
function on top level (but that has negative impacts for my idea). Is there any way to retrieve the companionObjectReference
? Or to achieve this behaviour? Maybe there is another annotation scanner that fits better for Kotlin? Any help is appreciated.Youssef Shoaib [MOD]
09/19/2022, 10:24 AMClass
out of it? Because then, you can do klass.kotlin.objectInstance!!
cpe
09/19/2022, 11:31 AM.kotlin
🙂 thanks for your help!
Solution now looks like:
val companion = classInfo.loadClass().kotlin
if (companion.isCompanion) {
companion.memberFunctions.filter { it.name == "onStartup" }.forEach { it.call(companion.objectInstance) }
}