Динамический прокси без явного указания типа в Scala - PullRequest
5 голосов
/ 10 октября 2010

возможно ли иметь метод, который принимает произвольный экземпляр и возвращает java.reflection.Proxy или аналогичный, который имеет тот же тип, что и исходный аргумент?

Я думаю, он должен выглядеть примерно так:

def createProxy[S](model: S)(implicit manifest: Manifest[S]): S = {...}

или это

def createProxy[S, T<:S](model: S)(implicit manifest: Manifest[S]): T = {...}

, где T - это подтип S, который является результатом комбинации всех реализованных интерфейсов, поскольку кажется, что я не могу проксикласс, но только интерфейсы.

Ответы [ 2 ]

3 голосов
/ 14 февраля 2011

Я думаю, что следующее должно сработать. Обратите внимание, что он не может вернуть S, поскольку, скорее всего, S не является интерфейсом.

import java.lang.reflect._

def createProxy[S](model: S)(implicit manifest: Manifest[S]) = {
  val clazz = manifest.erasure 
  Proxy.newProxyInstance(clazz.getClassLoader, clazz.getInterfaces, new InvocationHandler() {
    def invoke(proxy:Object, method:Method, args:scala.Array[Object]) = {
      method.invoke(model, args:_*)
    }
  })
}
2 голосов
/ 25 января 2014

В ситуациях, когда вы хотите проксировать объект, используя один интерфейс, вы можете сделать что-то вроде этого (основываясь на ответе Хирама Кирино):

import java.lang.reflect.{Method, InvocationHandler, Proxy}

def createProxy[I](proxee: I, interfaceClass: Class[I]): I = {
  assert(interfaceClass.isInterface, "interfaceClass should be an inteface class")
  Proxy.newProxyInstance(interfaceClass.getClassLoader, Array(interfaceClass), new InvocationHandler() {
    override def invoke(proxy: Object, method: Method, args: Array[Object]) = {
      println("before")
      val result = method.invoke(proxee, args: _*)
      println("after")
      result
    }
  }).asInstanceOf[I]
}

И имея интерфейс SessionSvc используйте его так:

val sessionSvc = createProxy(new SessionSvcMongo, classOf[SessionSvc])

Таким образом, мне удалось внедрить довольно безболезненное АОП в кодовую базу на основе шаблонов тортов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...