在groovy @Canonical bean构造函数调用中添加缺少的属性?
我是groovy的新手,刚开始探索它的元编程功能.我坚持在bean构造函数调用中添加缺少的属性.
在与FactoryBuilderSupport一起使用的类中,我想动态添加在构造函数调用期间尚未定义和提供的那些属性.这是精简版: @Canonical class MyClass { def startDate def additionalProperties = [:] def void propertyMissing(String name,value) { additionalProperties[name] = value } } 但是,如果我构造具有未知属性的类,则不会添加proprty,但我会得到一个MissingPropertyException: def thing = new MyClass(startDate: DateTime.now(),duration: 1234) 属性持续时间不存在,我预计它将通过propertyMissing处理.据我所知groovy,调用tuple-constructor会导致无参数构造函数调用,然后调用groovy生成的setter.那么为什么我会得到一个MissingPropertyException呢? 由于我是groovy的新手,我可能缺少一些基本的AST或MOP规则.我非常感谢你的帮助. 解决方法
如果您使用@Canonical并使用def定义第一个类对象,就像使用startDate一样,注释会生成以下构造函数:
@Canonical class MyClass { def startDate def additionalProperties = [:] def void propertyMissing(String name,value) { additionalProperties[name] = value } } // use reflection to see the constructors MyClass.class.getConstructors() 生成的构造函数: public MyClass() public MyClass(java.lang.Object) public MyClass(java.util.LinkedHashMap) public MyClass(java.lang.Object,java.lang.Object) 在@Canonical documentation中,您可以看到以下限制:
由于公共MyClass(java.util.LinkedHashMap)生成,您不能使用tuple-constructor,并且您得到MissingPropertyException. 令人惊讶的是,如果您使用类型而不是使用def定义您的第一个对象(请注意我说第一个),@ Canon注释不会添加公共MyClass(java.util.LinkedHashMap),然后您的元组构造函数调用工作,请参阅以下代码: @Canonical class MyClass { java.util.Date startDate def additionalProperties = [:] def void propertyMissing(String name,value) { additionalProperties[name] = value } } // get the constructors MyClass.class.getConstructors() // now your code works def thing = new MyClass(startDate: new java.util.Date(),duration: 1234) 现在创建的构造函数是: public MyClass() public MyClass(java.util.Date) public MyClass(java.util.Date,java.lang.Object) 因此,由于没有公共MyClass(java.util.LinkedHashMap),因此限制不适用,并且您的元组构造函数调用有效. 另外我想说,既然这个解决方案有效,我无法争辩为什么……我一次又一次地阅读@Canonical文档,我没有看到描述这种行为的部分,所以我不知道为什么以这种方式工作,我也做了一些尝试,我有点困惑,只有当第一个元素是def时,公共MyClass(java.util.LinkedHashMap)被创建,即: @Canonical class MyClass { def a int c } // get the constructors MyClass.class.getConstructors() 第一个对象定义为def … public MyClass() public MyClass(java.lang.Object) public MyClass(java.util.LinkedHashMap) // first def... public MyClass(java.lang.Object,int) 现在,如果我改变顺序: @Canonical class MyClass { int c def a } // get the constructors MyClass.class.getConstructors() 现在首先不是def和公共MyClass(java.util.LinkedHashMap)没有生成: public MyClass() public MyClass(int) public MyClass(int,java.lang.Object) 希望这可以帮助, (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |