我在尝试在Groovy中使用属性访问时遇到问题。看看下面的类:在groovy中拦截LOCAL属性访问
class Foo {
Map m = [:]
String bar
void getProperty(String name) {
m.get name
}
def setProperty(String name, value) {
m.set name, value
}
String getBarString() {
return bar // local access, does not go through getProperty()
}
}
它覆盖getter和setter简单地放置值成地图,而不是为对象的普通财产的空间。抽象地说,这有点愚蠢,但想象一下,不是将数据放入地图中,而是将其保存到数据库或其他有用的东西中。
不幸的是,下面的代码,现在将不起作用:
foo = new Foo()
foo.bar = "blerg" // using foo.bar invokes the setProperty interceptor
assert foo.bar == "blerg" // this will work fine as foo.bar here uses the getProperty interceptor
assert foo.getBarString() == "blerg" // explosion and fire! getBarString accesses bar locally without going through the getProperty interceptor so null will actually be returned.
当然有这个解决方法,可能的setProperty都设置在元属性和Map值等。然而,所有我的策略我们曾经想过要求程序员特别小心,以确保他们正确地访问类属性。
此外,一些建在真棒东西在Groovy(如@Delegate例如)使用直接元属性访问,而不是经历的getProperty所以下面永远不会成功:
class Meep {
String getMyMeep() {
return "MEEP!!!"
}
}
class Foo {
Map m = [:]
String bar
@Delegate Meep meep
void getProperty(String name) {
m.get name
}
def setProperty(String name, value) {
m.set name, value
}
String getBarString() {
return bar
}
}
foo = new Foo()
foo.meep = new Meep() // uses setProperty and so does not place the Meep in the Map m
foo.getMyMeep()
一个空指针异常是抛出最后一行,因为@Delegate使用MetaProperty直接访问(有效地this.meep.getMyMeep()而不是getProperty拦截器。不幸的是,'meep'为null,尽管getProperty('meep')不会。
In总之我在寻找的是一个解决以下标准的策略:
- 拦截属性读/写启用自动替代数据存储为其他开发商
- 透明或接近透明的界面(我不想让其他人的生活显著困难)
- 允许本地使用MetaProperty/this /等访问变量。访问方法
在此先感谢!
这将允许我从实例外部访问裸属性,而不是通过代理方法。但是,我真正想要做的是能够拦截**所有**访问。 我不知道是否有可能重写给定属性的MetaProperty.setProperty函数......或者甚至可以帮助。 – 2012-07-13 00:00:51