在Scala中使用反射的动态对象方法调用 [英] Dynamic object method invocation using reflection in scala

查看:43
本文介绍了在Scala中使用反射的动态对象方法调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望创建一种根据 Scala 中的模板 ID 动态调用逻辑的方法.所以模板 id 1 调用逻辑 a,模板 id 2 调用逻辑 b 等.逻辑将是多样的,但将具有相同的输入/输出.此外,不同模板 id 的数量将达到数千个并且不会提前知道,因此松散耦合感觉可行.

I'm looking to create a way to dynamically call logic depending on template id within scala. So template id 1 calls logic a, template id 2 call logic b, etc. The logic will be diverse but will have the same inputs/outputs. Also the number of different template ids will get into the thousands and will not be known ahead of time, so a loose coupling feels the way to go.

我已经开始研究使用 scala 2.11.1 的反射来做到这一点,并且当我知道要提前使用的逻辑但还没有找到动态使用反射的正确方法时可以静态使用反射,例如传递在模板 id 2 中将调用逻辑 b.

I've started looking at reflection to do this using scala 2.11.1 and can statically use reflection when I know the logic to be used ahead of time but have not found the correct way to dynamically use reflection, so for example passing in template id 2 will call logic b.

下面是一个简化的例子,展示了静态版本的工作原理以及我目前为动态版本所拥有的骨架.

Below is a cut down example showing how the static version works and the skeleton I have so far for the dynamic version.

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)

}

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

What needs to be added/changed to the dynamicInvocation method to make this work, or should I be using a different approach?

推荐答案

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

You need to get an instance mirror for your module, on which you can reflect the method.

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")
}

这篇关于在Scala中使用反射的动态对象方法调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆