我正在尝试实现一个代理模式,以便我可以在必要时动态交换底层实例以及触发交换的扩展方法。我以前在 Java 中实现过这个,但我在 Scala 中遇到了麻烦。
这是我的场景:
class Client { ...library code... }
trait DynamicClient extends Client {
def swap: Client
}
class Provider extends Provider[DynamicClient] {
def get():DynamicClient {
java.lang.reflect.Proxy.newProxyInstance(
classOf[DynamicClient].getClassLoader,
Array(classOf[DynamicClient]),
handler)
.asInstanceOf[DynamicClient]
}
}
class DynamicClientHandler extends java.lang.reflect.InvocationHandler {
var client:Client = createNewClient()
def swap(): {
client = createNewClient()
client
}
def createNewClient():Client: { ... }
def invoke(proxy: AnyRef, method: java.lang.reflect.Method, args: Array[AnyRef]): AnyRef = {
method.getDeclaringClass match {
case dyn if dyn == classOf[DynamicClient] => swap()
case _ => method.invoke(client, args: _*)
}
}
}
现在的问题是:当我从 Proxy 对象上的 DynamicClient 或 Object 调用方法时,它们工作得很好。
val dynamicClient = injector.instanceOf[DynamicClient]
val initial = dynamicClient.client
val client = dynamicClient.swap()
val dynamicClient.toString // "Client@1234" (Object impl of toString via client instance)
assert(client != initial) //passes just fine, the underlying client is re-initialized
对属于 Client 类的方法的任何调用在到达调用处理程序之前都会失败。
//Both of the following scenarios fail independently of the other
//ERROR:
dynamicClient.asInstanceOf[Client]
//ERROR:
dynamicClient.doSomeClientMethod()
使用此异常跟踪:
java.lang.ClassCastException: com.sun.proxy.$Proxy22 cannot be cast to Client
为什么我会得到这个演员表异常?有没有更好的方法来处理 Scala 中的代理调用处理与 Java 方式?