一直没瞧得起Remoting直接调用Java对象方法这个功能,感觉就是反射一类的,昨晚偶然看了下RemoteObject的源码,发现了Proxy这个东西,它提供了一些类似PHP的魔术方法(如__set();__get();__call();等)的功能:
callProperty(name:*, ... rest):* Overrides the behavior of an object property that can be called as a function. Proxy deleteProperty(name:*):Boolean Overrides the request to delete a property. Proxy getDescendants(name:*):* Overrides the use of the descendant operator. Proxy getProperty(name:*):* Overrides any request for a property's value. Proxy hasProperty(name:*):Boolean Overrides a request to check whether an object has a particular property by name. Proxy isAttribute(name:*):Boolean Checks whether a supplied QName is also marked as an attribute. Proxy nextName(index:int):String Allows enumeration of the proxied object's properties by index number to retrieve property names. Proxy nextNameIndex(index:int):int Allows enumeration of the proxied object's properties by index number. Proxy nextValue(index:int):* Allows enumeration of the proxied object's properties by index number to retrieve property values. Proxy setProperty(name:*, value:*):void Overrides a call to change a property's value. Proxy
从下面的连接我们可以找到相关用法的测试程序
http://life.neophi.com/danielr/2008/02/puzzling_proxy_problem.html
下面是测试代码
package com.neophi.test { import flash.utils.Proxy; import flash.utils.flash_proxy; public dynamic class MyProxy extends Proxy { override flash_proxy function callProperty(name:*, ... rest):* { trace("callProperty", name, rest); flash_proxy::isAttribute(name); return null; } override flash_proxy function deleteProperty(name:*):Boolean { trace("deleteProperty", name); flash_proxy::isAttribute(name); return false; } override flash_proxy function getDescendants(name:*):* { trace("getDescendants", name); flash_proxy::isAttribute(name); return null; } override flash_proxy function getProperty(name:*):* { trace("getProperty", name); flash_proxy::isAttribute(name); return null; } override flash_proxy function hasProperty(name:*):Boolean { trace("hasProperty", name); flash_proxy::isAttribute(name); return false; } // Don't override isAttribute(), it is a utility function // used by methods that specify a name:* parameter // to determine if the name argument was specified as an // attribute. It doesn't look like there is any other // way to determine if a name was specified as an // attribute besides calling Proxy's isAttribute() // implementation. override flash_proxy function isAttribute(name:*):Boolean { var result:Boolean = super.flash_proxy::isAttribute(name); trace("isAttribute", name, result); return result; } override flash_proxy function nextName(index:int):String { trace("nextName", index); return null; } override flash_proxy function nextNameIndex(index:int):int { trace("nextNameIndex", index); return (1 - index); } override flash_proxy function nextValue(index:int):* { trace("nextValue", index); return null; } override flash_proxy function setProperty(name:*, value:*):void { trace("setProperty", name, value); flash_proxy::isAttribute(name); } } }
private function go():void { namespace myNamespace = "com.neophi.test"; var myProxy:MyProxy = new MyProxy(); // callProperty() myProxy.foo(); // Compiler error: 1041: Attributes are not callable. // myProxy.@foo(); myProxy.myNamespace::foo(); // Compiler error: 1041: Attributes are not callable. // myProxy.@myNamespace::foo(); // deleteProperty(): uses isAttribute() delete myProxy.foo; delete myProxy.@foo; delete myProxy.myNamespace::foo; delete myProxy.@myNamespace::foo; // getDescendents(): uses isAttribute() myProxy..foo; myProxy..@foo; myProxy..myNamespace::foo; myProxy..@myNamespace::foo; // getProperty(): uses isAttribute() myProxy.foo; myProxy.@foo; myProxy.myNamespace::foo; myProxy.@myNamespace::foo; // hasProperty() "foo" in myProxy; // Compiler error: 1084: Syntax error: expecting identifier before foo. // @"foo" in myProxy; new QName(myNamespace, "foo") in myProxy; // Compiler error: 1084: Syntax error: expecting identifier before new. // @new QName(myNamespace, "foo") in myProxy; // nextName(): uses nextNameIndex() for (var string:String in myProxy) { trace(string); } // nextValue(): uses nextNameIndex() for each (var object:Object in myProxy) { trace(object); } // setProperty(): uses isAttribute() myProxy.foo = "bar"; myProxy.@foo = "bar"; myProxy.myNamespace::foo = "bar"; myProxy.@myNamespace::foo = "bar"; }
输出结果
callProperty foo isAttribute foo false callProperty com.neophi.test::foo isAttribute com.neophi.test::foo false deleteProperty foo isAttribute foo false deleteProperty foo isAttribute foo true deleteProperty com.neophi.test::foo isAttribute com.neophi.test::foo false deleteProperty com.neophi.test::foo isAttribute com.neophi.test::foo true getDescendants foo isAttribute foo false getDescendants foo isAttribute foo true getDescendants com.neophi.test::foo isAttribute com.neophi.test::foo false getDescendants com.neophi.test::foo isAttribute com.neophi.test::foo true getProperty foo isAttribute foo false getProperty foo isAttribute foo true getProperty com.neophi.test::foo isAttribute com.neophi.test::foo false getProperty com.neophi.test::foo isAttribute com.neophi.test::foo true hasProperty foo isAttribute foo false hasProperty com.neophi.test::foo isAttribute com.neophi.test::foo false nextNameIndex 0 nextName 1 null nextNameIndex 1 nextNameIndex 0 nextValue 1 null nextNameIndex 1 setProperty foo bar isAttribute foo false setProperty foo bar isAttribute foo true setProperty com.neophi.test::foo bar isAttribute com.neophi.test::foo false setProperty com.neophi.test::foo bar isAttribute com.neophi.test::foo true