如何获得方法的注释在斯卡拉2.11 [英] How to get the annotations of a method in Scala 2.11

查看:150
本文介绍了如何获得方法的注释在斯卡拉2.11的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们假设一个控制器对象是这样的:

Let's assume a controller object like this:

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 =>
    ...
  }

  ...
}

我如何获得在运行时,验证方法的注释值?我试过这样:

How do I get the annotation values of the authenticate method at runtime? I've tried this:

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
}   

methodAnnotations 返回指定注解指定的方法,并调用这样的:

methodAnnotations returns the specified annotation for the specified method and is invoke like this:

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

问题是,当我编译code以上我总是得到以下警告:

The problem is that when I compile the code above I always get the following warnings:

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

什么是获得使用Scala 2.11方法注释的正确方法?

What's the correct way to get method annotations with scala 2.11?

推荐答案

也许溶液内特建议是最清洁和高效的......但在我的情况下,它需要太多的重构,所以我刚刚决定仍然使用Scala的反思。这里是我的解决方案:

Probably the solution suggested by Nate is the most clean and efficient... but in my case it would require too much refactoring, so I've just decided to still use Scala reflection. Here is my solution:

package utils.common

import scala.reflect.runtime.universe._

/**
  * Provides functionality for obtaining reflective information about
  * classes and objects.
  */
object ReflectHelper {

  /**
    * Returns a `Map` from annotation names to annotation data for
    * the specified type.
    *
    * @tparam T The type to get class annotations for.
    * @return The class annotations for `T`.
    */
  def classAnnotations[T: TypeTag]: Map[String, Map[String, Any]] = {
    typeOf[T].typeSymbol.asClass.annotations.map { a =>
      a.tree.tpe.typeSymbol.name.toString -> a.tree.children.withFilter {
        _.productPrefix eq "AssignOrNamedArg"
      }.map { tree =>
        tree.productElement(0).toString -> tree.productElement(1)
      }.toMap
    }.toMap
  }

  /**
    * Returns a `Map` from method names to a `Map` from annotation names to
    * annotation data for the specified type.
    *
    * @tparam T The type to get method annotations for.
    * @return The method annotations for `T`.
    */
  def methodAnnotations[T: TypeTag]: Map[String, Map[String, Map[String, Any]]] = {
    typeOf[T].decls.collect { case m: MethodSymbol => m }.withFilter {
      _.annotations.length > 0
    }.map { m =>
      m.name.toString -> m.annotations.map { a =>
        a.tree.tpe.typeSymbol.name.toString -> a.tree.children.withFilter {
         _.productPrefix eq "AssignOrNamedArg"
        }.map { tree =>
          tree.productElement(0).toString -> tree.productElement(1)
        }.toMap
      }.toMap
    }.toMap
  }
}

我希望它能帮助。

I hope it helps.

这篇关于如何获得方法的注释在斯卡拉2.11的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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