访问Grails域类上的字段注释

访问Grails域类上的字段注释,grails,groovy,Grails,Groovy,我试图在我的域类上注释字段,但我无法像通常的Java字段那样在运行时通过反射获得它们 我的带注释的域类如下所示: class MyDomainClass { @MyAnnotation String myField } 通过反射访问myField的Java方法不起作用: MyDomainClass.class.getField("myField") //throws java.lang.NoSuchFieldException Grails检查域类的方法不公开字段注释: ne

我试图在我的域类上注释字段,但我无法像通常的Java字段那样在运行时通过反射获得它们

我的带注释的域类如下所示:

class MyDomainClass {
    @MyAnnotation
    String myField
}
通过反射访问
myField
的Java方法不起作用:

MyDomainClass.class.getField("myField") //throws java.lang.NoSuchFieldException
Grails检查域类的方法不公开字段注释:

new DefaultGrailsDomainClass(MyDomainClass).getPersistentProperty("myField").??? //there is nothing similar to getAnnotations()

如何检索与域字段关联的注释?

这不是字段,而是属性。当您在Groovy类中声明一个类作用域变量,比如没有作用域修饰符(
public
protected
,等等)时,Groovy编译器会将其转换为具有相同类型和名称的私有字段,以及基本上相同的getter和setter方法

class MyDomainClass {
   @MyAnnotation
   private String myField

   public String getMyField() {
      return myField
   }
   public void setMyField(String s) {
      myField = s
   }
}
但它不会覆盖现有的getter或setter

当您访问属性时,您最终会调用getter或setter,如果您添加了这些方法并包含
println
语句,就可以看到getter或setter。通过这种方式,Java类可以通过这些方法访问属性,Groovy假装您正在直接读取或写入字段,但在幕后,您最终调用了与Java相同的方法

这样做的一个好处是,如果您以后决定在设置或获取值时添加一些逻辑,您可以定义相应的方法并添加所需的内容,而无需更改访问属性的代码,因为在Groovy中,您仍然可以将其视为字段并调用自定义方法,Java类将一直在调用setter和getter

getFields()
只返回公共字段,但
getDeclaredFields()
返回所有字段,因此,由于实际字段是私有的,因此需要使用
getDeclaredFields()
(或属性访问表单
declaredFields


Grails不使用注释,因为Graeme(和其他人)觉得它们很难看和笨重,而不是因为它们不可访问。

这使用delegate.class.declaredFields:
def theField=delegate.class.declaredFields.find{field->field.name==it.name}
然后
theField.isAnnotationPresent(MyAnnotation)
grails的神奇之处是什么?我还想知道为什么grails不使用注释来设置字段特定的信息(默认值等),这让我认为这些注释在运行时无法检索。太好了。对于Graeme的关注点,我理解注释并不是一个共识,但我自己发现它是一个保持可维护性的极好工具,我正在考虑覆盖grails默认行为以提供与属性相关的信息。如果其他人觉得它有用,我会尝试把它作为一个插件。你听到过这样的要求吗?