Groovy:自动扩展属性

时间:2015-10-15 12:59:27

标签: groovy

如果我有这样一个时髦的课:

class WebSession{
    String firstName
    String lastName
    String email
}

我希望能够使用自动设置器来设置值。例如:

WebSessionuser = new WebSession()
webSession.firstName = 'John'

但是它调用的setter做了额外的事情,比如记录某些内容或者将对象保留为缓存。

如何在不必手动定义所有设置器的情况下执行此操作?到目前为止,我有类似的东西,但我不能让它工作:

    webSession.properties.each{ key, value ->
        if ( key != 'class' ) {
            String methodName = "set${key.capitalize()}";
            WebSession.metaClass[key]."${methodName}" = { -> delegate
                System.out.println("Setting key: ${key}");
                webSession[key] = delegate;
            }
        }

    }

另外,我不知道是否循环遍历属性名称减去'class'是hacky并且有更好的方法来获取声明的字段。

1 个答案:

答案 0 :(得分:2)

您可以通过实施void setProperty(String, Object)Object getProperty(String)拦截所有的getter和setter。这是一个例子:

实施例

def a = new WebSessionDecorator(new WebSession())

a.firstName = 'John'

println a.firstName

class WebSession {
    String firstName
    String lastName
    String email
}

class WebSessionDecorator {
    private WebSession delegate

    WebSessionDecorator(WebSession webSession) {
        this.delegate = webSession
    }

    void setProperty(String name, Object value) {
        println "LOG: Setting $name to $value"
        delegate.setProperty(name, value)        
    }

    def getProperty(String name) {
        println "LOG: Returning $name"
        delegate.getProperty(name)
    }
}

输出

输出如下:

LOG: Setting firstName to John
LOG: Returning firstName
John

说明

WebSessionDecorator拦截所有属性访问权限,为您提供进行任何操作的机会。然后,它将属性访问委托给实际的WebSession

我选择使用装饰器以避免重复调用getProperty()setProperty(),并且仅在适用时才可以使用装饰器。例如,您可能不想在单元测试中使用它。