(背景:我已经和Java bean一起工作了大约18年的时间;我已经和Freemarker合作了一两个星期。: - ))
我有一个手工编织的BeanInfo
代表一个不遵循"普通"的类的属性。 (但显然是随意的)get
/ set
- 方法命名方式。
从语义上讲,对于名为x
的Java bean属性,您可以在此类上调用一个名为x()
的方法。
所以我的BeanInfo
实现(Freemarker正在查找和加载)实现了这种模式。细
有问题的类实际上有一个名为target()
的方法,它返回一个特定的对象(让我们在这里称它为Target
),并由PropertyDescriptor
表示其名称为target
,其readMethod
为该方法。细
在我的Freemarker模板中,如果我这样做:
theObject.target
...我收到一条错误消息,指出target
,实际上是一种方法,而不是属性,表明我的PropertyDescriptor
虽然在技术上是可以找到的,但却没有被咨询过。如果我将其更改为:
theObject.target()
......然后一切正常。换句话说,target()
方法似乎被Freemarker视为一种方法 - 它就像Freemarker一样没有"通过"到PropertyDescriptor
,否则会告诉它这实际上是"读取方法" Java bean属性。
我尝试修改我的BeanInfo
以返回MethodDescriptors
的空列表,认为可能是问题:如果您从null
中的特定方法返回BeanInfo
然后Introspector
对该事做了低级内省。 null
是默认值。因此,如果您从null
返回BeanInfo#getMethodDescriptors()
,则Introspector
可能会找到您班级中的所有公开方法并为其创建MethodDescriptor
。
无论如何,所以我返回了MethodDescriptor
s的空列表,希望我可以强迫Freemarker不要"看到" target
作为方法,但作为Java bean属性("通过"到BeanInfo
PropertyDescriptor
如上所述)。这没用。
简而言之,我怎样才能做到:
someObject.target
... incantation访问我的属性描述符,而不是target()
方法?
答案 0 :(得分:1)
当FreeMarker使用java.beans.Introspector
来发现bean属性和动作时,它确实尊重BeanInfo
的内容。问题是,在您的情况下,将返回PropertyDescriptor
- s和MethodDescriptor
- s与冲突的名称。由于模板语言没有单独的属性和方法命名空间,因此必须将另一个命名空间。默认情况下,方法阴影属性(现在不太实用,因为流畅的API通常使用Foo foo()
而不是Foo getFoo()
等方法。您可以通过将methodAppearanceFineTuner
的{{1}}属性设置为始终调用DefaultObjectWrapperBuilder
的{{1}}对象来进行更改。