使用scala中的反射进行动态对象方法调用

Mar*_*ill 0 reflection scala

我正在寻找一种方法来动态调用逻辑,具体取决于scala中的模板ID.因此模板id 1调用逻辑a,模板id 2调用逻辑b等.逻辑将是多样的但具有相同的输入/输出.此外,不同模板ID的数量将达到数千个,并且不会提前知道,因此松耦合感觉要走的路.

我已经开始使用scala 2.11.1来查看反射,并且当我知道提前使用的逻辑但是没有找到动态使用反射的正确方法时可以静态地使用反射,所以例如传入模板id 2将调用逻辑b.

下面是一个简短的示例,显示静态版本的工作原理以及我到目前为止动态版本的骨架.

package thePackage

import scala.reflect.runtime.{universe => ru}

trait theTrait { def theMethod(x: String): Unit }

// the different logic held in different objects
object object1 extends theTrait {
  def theMethod(x: String) = { println("a " + x ) }
}

object object2 extends theTrait { 
  def theMethod(x: String) = { println("b " + x ) }
}

object object3 extends theTrait {
  def theMethod(x: String) = { println("c " + x ) }
}

// run static/dynamic reflection methods
object ReflectionTest {

  // "static" invocation calling object1.theMethod
  def staticInvocation() = {
    val m = ru.runtimeMirror(getClass.getClassLoader)
    val im = m.reflect(thePackage.object1)
    val method = ru.typeOf[thePackage.object1.type]
                   .decl(ru.TermName("theMethod")).asMethod
    val methodRun = im.reflectMethod(method)
    methodRun("test")
  }

  staticInvocation

  // "dynamic" invocation using integer to call different methods
  def dynamicInvocation( y: Integer) = {
    val m = ru.runtimeMirror(getClass.getClassLoader)
    val module = m.staticModule("thePackage.object" + y)
    val im = m.reflectModule(module)

    //  stuck... static approach does not work here

  }

  dynamicInvocation(1)
  dynamicInvocation(2)
  dynamicInvocation(3)

}
Run Code Online (Sandbox Code Playgroud)

需要添加/更改为dynamicInvocation方法才能使其工作,或者我应该使用不同的方法?

Iul*_*gos 5

您需要为模块获取一个实例镜像,您可以在其上反映该方法.

def dynamicInvocation( y: Integer) = {
  val m = ru.runtimeMirror(getClass.getClassLoader)
  val module = m.staticModule("thePackage.object" + y)
  val im = m.reflectModule(module)
  val method = im.symbol.info.decl(ru.TermName("theMethod")).asMethod

  val objMirror = m.reflect(im.instance)
  objMirror.reflectMethod(method)("test")
}
Run Code Online (Sandbox Code Playgroud)