Freemarker 是否支持 MethodDescriptors?
Does Freemarker honor MethodDescriptors?
(背景:我断断续续地使用 Java beans 大约 18 年;我使用 Freemarker 一两周。:-))
我有一个手工工具 BeanInfo
表示 class 的属性,它不遵循 "ordinary"(但显然是任意的)get
/set
-方法命名风格。
从语义上讲,对于名为 x
的 Java bean 属性,您将在此 class 上调用名为 x()
的方法。
所以我的 BeanInfo
实现(Freemarker 正在查找和加载)实现了这个模式。很好。
问题中的class其实有一个方法叫target()
,return是某个对象(这里就叫Target
),表示为一个 PropertyDescriptor
其名称是 target
并且其 readMethod
是该方法。很好。
在我的 Freemarker 模板中,如果我这样做:
theObject.target
...我收到一条错误消息,说 target
实际上是一种方法,而不是 属性,这表明我的 PropertyDescriptor
虽然在技术上可以找到,但没有被参考.如果我改为:
theObject.target()
...然后一切正常。换句话说,target()
方法似乎被 Freemarker 视为一种方法——就好像 Freemarker 不是 "getting through" 到 PropertyDescriptor
,否则它会告诉它这实际上是"read method" 一个 Java bean 属性.
我尝试将我的 BeanInfo
编辑为 return MethodDescriptors
的空列表,认为这可能是问题所在:如果您 return null
从 BeanInfo
中的特定方法,然后 Introspector
对那个东西进行低级内省。 null
是默认值。因此,如果您从 BeanInfo#getMethodDescriptors()
return null
,Introspector
可能会在您的 class 中找到所有 public 方法并创建 MethodDescriptor
给他们。
无论如何,所以我 return 编辑了一个 MethodDescriptor
的空列表,希望我可以强制 Freemarker 不是 "seeing" target
作为一种方法,而是作为一个 Java beans 属性("falling through" 到我的 BeanInfo
的 PropertyDescriptor
,如上所述)。这没有用。
简而言之,我怎样才能使我的:
someObject.target
...咒语访问我的 属性 描述符,而不是 target()
方法?
由于 FreeMarker 使用 java.beans.Introspector
来发现 bean 属性和操作,因此它确实遵循 BeanInfo
的内容。问题是,在您的情况下, return PropertyDescriptor
-s 和 MethodDescriptor
-s 的名称会冲突。由于模板语言没有用于属性和方法的单独命名空间,因此一个必须隐藏另一个。默认情况下,方法会隐藏属性(现在这不是很实用,因为 fluent API-s 通常有像 Foo foo()
而不是 Foo getFoo()
这样的方法)。您可以通过将 DefaultObjectWrapperBuilder
的 methodAppearanceFineTuner
属性 设置为总是调用 decision.setMethodShadowsProperty(false)
.
的 MethodAppearanceFineTurner
对象来更改它
(背景:我断断续续地使用 Java beans 大约 18 年;我使用 Freemarker 一两周。:-))
我有一个手工工具 BeanInfo
表示 class 的属性,它不遵循 "ordinary"(但显然是任意的)get
/set
-方法命名风格。
从语义上讲,对于名为 x
的 Java bean 属性,您将在此 class 上调用名为 x()
的方法。
所以我的 BeanInfo
实现(Freemarker 正在查找和加载)实现了这个模式。很好。
问题中的class其实有一个方法叫target()
,return是某个对象(这里就叫Target
),表示为一个 PropertyDescriptor
其名称是 target
并且其 readMethod
是该方法。很好。
在我的 Freemarker 模板中,如果我这样做:
theObject.target
...我收到一条错误消息,说 target
实际上是一种方法,而不是 属性,这表明我的 PropertyDescriptor
虽然在技术上可以找到,但没有被参考.如果我改为:
theObject.target()
...然后一切正常。换句话说,target()
方法似乎被 Freemarker 视为一种方法——就好像 Freemarker 不是 "getting through" 到 PropertyDescriptor
,否则它会告诉它这实际上是"read method" 一个 Java bean 属性.
我尝试将我的 BeanInfo
编辑为 return MethodDescriptors
的空列表,认为这可能是问题所在:如果您 return null
从 BeanInfo
中的特定方法,然后 Introspector
对那个东西进行低级内省。 null
是默认值。因此,如果您从 BeanInfo#getMethodDescriptors()
return null
,Introspector
可能会在您的 class 中找到所有 public 方法并创建 MethodDescriptor
给他们。
无论如何,所以我 return 编辑了一个 MethodDescriptor
的空列表,希望我可以强制 Freemarker 不是 "seeing" target
作为一种方法,而是作为一个 Java beans 属性("falling through" 到我的 BeanInfo
的 PropertyDescriptor
,如上所述)。这没有用。
简而言之,我怎样才能使我的:
someObject.target
...咒语访问我的 属性 描述符,而不是 target()
方法?
由于 FreeMarker 使用 java.beans.Introspector
来发现 bean 属性和操作,因此它确实遵循 BeanInfo
的内容。问题是,在您的情况下, return PropertyDescriptor
-s 和 MethodDescriptor
-s 的名称会冲突。由于模板语言没有用于属性和方法的单独命名空间,因此一个必须隐藏另一个。默认情况下,方法会隐藏属性(现在这不是很实用,因为 fluent API-s 通常有像 Foo foo()
而不是 Foo getFoo()
这样的方法)。您可以通过将 DefaultObjectWrapperBuilder
的 methodAppearanceFineTuner
属性 设置为总是调用 decision.setMethodShadowsProperty(false)
.
MethodAppearanceFineTurner
对象来更改它