Freemarker 是否尊重方法描述符?



(背景:我已经断断续续地使用 Java bean 大约 18 年了;我已经使用Freemarker一两个星期了。 :-))

我有一个手工工具BeanInfo,它表示一个不遵循方法命名的"普通"(但显然是任意的)get/set风格的类的属性。

从语义上讲,对于名为x的 Java Bean 属性,您将在此类上调用名为x()的方法。

所以我的BeanInfo实现(Freemarker 正在查找和加载)实现了这种模式。 好。

有问题的类实际上有一个名为target()的方法,它返回某个对象(我们在这里称之为Target),它由一个名称为targetreadMethod是该方法的PropertyDescriptor表示。 好。

在我的自由标记模板中,如果我这样做:

theObject.target

。我收到一个错误,说target实际上是一种方法,而不是属性,这表明我的PropertyDescriptor虽然在技术上可以找到,但没有被咨询。 如果我将其更改为:

theObject.target()

。然后一切正常。 换句话说,target()方法似乎被Freemarker视为一种方法——就像Freemarker没有"通过"PropertyDescriptor,否则它会告诉它这实际上是Java bean属性的"读取方法"。

我尝试编辑我的BeanInfo以返回一个空的MethodDescriptors列表,认为这可能是问题所在:如果您从BeanInfo中的特定方法返回null,那么Introspector会对该内容进行低级内省。null是默认值。 因此,如果您从BeanInfo#getMethodDescriptors()返回nullIntrospector大概会找到类中的所有公共方法并为它们创建MethodDescriptor

无论如何,所以我返回了一个空的MethodDescriptor列表,希望我可以强迫Freemarker不要"看到"target作为一个方法,而是作为一个Java bean属性(如上所述"落入"我BeanInfoPropertyDescriptor)。 这行不通。

简而言之,我怎样才能使我的:

someObject.target

。咒语访问我的属性描述符,而不是target()方法?

由于FreeMarker使用java.beans.Introspector来发现bean属性和操作,因此它确实尊重BeanInfo的内容。问题是,在您的情况下,这将返回名称冲突的PropertyDescriptor-s 和MethodDescriptor-s。由于模板语言没有单独的属性和方法命名空间,因此一个必须隐藏另一个。默认情况下,方法隐藏属性(这在今天不是很实用,因为流畅的 API-s 通常具有像Foo foo()而不是Foo getFoo()这样的方法)。您可以通过将DefaultObjectWrapperBuildermethodAppearanceFineTuner属性设置为始终调用decision.setMethodShadowsProperty(false)MethodAppearanceFineTurner对象来更改它。

最新更新