Freemarker是否尊重MethodDescriptors?

时间:2017-03-31 14:48:36

标签: java javabeans freemarker

(背景:我已经和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()方法?

1 个答案:

答案 0 :(得分:1)

当FreeMarker使用java.beans.Introspector来发现bean属性和动作时,它确实尊重BeanInfo的内容。问题是,在您的情况下,将返回PropertyDescriptor - s和MethodDescriptor - s与冲突的名称。由于模板语言没有单独的属性和方法命名空间,因此必须将另一个命名空间。默认情况下,方法阴影属性(现在不太实用,因为流畅的API通常使用Foo foo()而不是Foo getFoo()等方法。您可以通过将methodAppearanceFineTuner的{​​{1}}属性设置为始终调用DefaultObjectWrapperBuilder的{​​{1}}对象来进行更改。