Scala Reflection:如何迁移到2.11版

时间:2014-08-14 18:07:40

标签: scala reflection

刚刚从Scala 2.10.3切换到Scala 2.11.1 ...并且在尝试编译此代码时...

def methodAnnotations[T: TypeTag]: Map[String, Map[String, Map[String, JavaArgument]]] = {
  typeTag[T].tpe.declarations.collect { case m: MethodSymbol => m }.map { m =>
    val methodName = m.name.toString
    val annotations =  m.annotations.map { a =>
      val annotationName = a.tpe.typeSymbol.name.toString
      val annotationArgs = a.javaArgs.map {
        case (name, value) => name.toString -> value
      }
      annotationName -> annotationArgs
    }.toMap
    methodName -> annotations
  }.toMap
}   

...我收到以下警告:

type JavaArgument in trait Annotations is deprecated: Use `Annotation.tree` to inspect annotation arguments
method tpe in trait AnnotationApi is deprecated: Use `tree.tpe` instead

methodAnnotations返回方法的注释,我这样调用它:

val mAnnotations = methodAnnotations[T]
val nickname = mAnnotations("myMethodName")("MyAnnotationName")("myAnnotationMemberName").asInstanceOf[LiteralArgument].value.value.asInstanceOf[String]

我不清楚如何将此代码移植到scala 2.11 ...我试图在Web上找到一个例子,但没办法。 TX。

修改

也许值得为您提供一个使用示例。我的控制器对象有这样的方法......

object Users extends Controller {

...

  @ApiOperation(
    httpMethod = "POST",
    nickname = "authenticate",
    value = "Authenticates an user",
    notes = "Returns the JSON Web Token to be used in any subsequent request",
    response = classOf[models.auth.api.Jwt])
  def authenticate = SecuredAction[Users.type]("authenticate").async(parse.json) { implicit request =>
    ...
  }

  ...
}

...我需要通过应用程序中的其他地方的反射来检索注释的属性,如下所示:

val mAnnotations = methodAnnotations[Users.type]
val nickname = mAnnotations("authenticate")("ApiOperation")("nickname").asInstanceOf[LiteralArgument].value.value.asInstanceOf[String]
// do something interesting with nichname...

1 个答案:

答案 0 :(得分:0)

我会尝试类似的事情:

test("Users", "authenticate")

def test(className: String, mName: String) = {
  import scala.reflect.runtime._
  import scala.reflect.runtime.{universe => ru}

  val typ: universe.ClassSymbol = universe.runtimeMirror(Thread.currentThread().getContextClassLoader).staticClass(className)
  val methodSymbol = typ.info.decls.find(s => s.name.toString == mName)
  val apiOperationType = ru.typeOf[ApiOperation]
  val maybeAnnotation: Option[api.JavaUniverse#Annotation] = methodSymbol.get.annotations.find(
  a => a.tree.tpe == apiOperationType )

  val trees: List[api.JavaUniverse#Tree] = maybeAnnotation.get.tree.children.tail
trees.foreach(a => 
    //access the attributes (nickname) here:
    println(ru.showRaw(a)))
}