Scala 有没有一种方法可以告诉类中的所有方法执行函数调用,而不必将这些函数调用写入每个方法

Scala 有没有一种方法可以告诉类中的所有方法执行函数调用,而不必将这些函数调用写入每个方法,scala,Scala,我正在对数十个应该授权的服务的请求呼叫进行编码 我注意到我已经在服务类中的所有方法的开头写了很多复制粘贴代码,因为它们在使用任何服务之前都必须经过授权 小例子 class AuthorizationService { val authorized = List("James", "007") def authorize(user: String) = { if (!authorized.contains(user)) throw new RuntimeException(s"U

我正在对数十个应该授权的服务的请求呼叫进行编码

我注意到我已经在服务类中的所有方法的开头写了很多复制粘贴代码,因为它们在使用任何服务之前都必须经过授权

小例子

class AuthorizationService {
  val authorized = List("James", "007")

  def authorize(user: String) = {
    if (!authorized.contains(user)) throw new RuntimeException(s"User '$user' not authorized")
  }
}

class Service1 {

  val authorizationService = new AuthorizationService

  def doThis(user: String) = {
    authorizationService.authorize(user)
    println(s"User '$user' did this")
  }

  def doThat(user: String) = {
    authorizationService.authorize(user)
    println(s"User '$user' did that")
  }
}

现在,假设有30个服务类,每个类有三个方法,我继续按照我的方式进行授权,最终编写了90个函数调用。

您可以使用一个粗略的组合模式:

class ServiceAuthorizationExecutor {
   def call(user: String, delegate: DELGATE_TYPE) = {
      authorizationService.authorize(user)
      delegate()
   }
}

像这样的可能。。。它仍然需要您的服务进行更改,但不需要更改太多:

 object AuthToken {
    implicit def auth(s: String)(implicit service: AuthService) = { 
      service.authorize(s)
      AuthToken(s)
    }
 }
 case class AuthToken private[AuthToken] (s: String) {
    override def toString = s;
 }

 class Service1 {
   implicit val authorizationService = new AuthorizationService
   def doThis(user: AuthToken) = {
     println(s"User '$user' did this")
   }
 }

现在,如果您执行
newservice1().doThis(“James”)
,它将首先隐式调用您的身份验证服务以将名称转换为令牌

您可以这样使用它:

object Tester {

  class AuthorizationService {
    val authorized = List("James", "007")

    def authorize(user: String) = {
      if (!authorized.contains(user)) throw new RuntimeException(s"User '$user' not authorized")
    }
  }


  def authorize(businessLogic: => Unit)(implicit
                                        authorizationService: AuthorizationService,
                                        user: String): Unit = {
    // authorization logic
    authorizationService.authorize(user)
    println(s"User '$user' did this")

    // actual code that needs to be executed
    businessLogic
  }

  class Service1(implicit val authorizationService: AuthorizationService) {
    def doThis(implicit user: String) = authorize {
      println("doThis()")
    }

    def doThat(implicit user: String) = authorize {
      println("doThat()")
    }
  }

  def main(args: Array[String]) {
    implicit val authorizationService = new AuthorizationService
    val s = new Service1()
    s.doThat("James")
    s.doThat("007")
    s.doThat("Neo")
  }
}

这是一个典型的AOP问题。不过,我上一次看AOP是12年前,所以我不确定它的状态如何。

这也行得通,但我没有足够的声望来支持:)这应该是一个评论,它没有回答问题。