(背景:我断断续续地使用 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
对那件事进行低层次的内省(introspection)。和null
是默认值。所以如果你返回null
来自BeanInfo#getMethodDescriptors()
, Introspector
大概会找到类中的所有公共(public)方法并创建 MethodDescriptor
为他们服务。
无论如何,我返回了一个空列表 MethodDescriptor
s,希望我可以强制 Freemarker 不“看到”target
作为一种方法,但作为 Java beans 属性(“落入”我的 BeanInfo
的 PropertyDescriptor
,如上所述)。这不起作用。
简而言之,我怎样才能:
someObject.target
...咒语访问我的属性描述符,而不是 target()
方法?
最佳答案
由于 FreeMarker 使用 java.beans.Introspector 来发现 bean 属性和操作,因此它确实尊重 BeanInfo 的内容。问题是,在您的情况下,将返回具有冲突名称的 PropertyDescriptor
-s 和 MethodDescriptor
-s。由于模板语言没有单独的属性和方法命名空间,因此其中一个必须隐藏另一个。默认情况下,方法会隐藏属性(现在这不太实用,因为流畅的 API 通常具有像 Foo foo()
这样的方法,而不是 Foo getFoo()
)。您可以通过将 DefaultObjectWrapperBuilder
的 methodAppearanceFineTuner
属性设置为始终调用 decision.setMethodShadowsProperty(false) 的
.MethodAppearanceFineTurner
对象来更改此设置
关于java - Freemarker 是否尊重方法描述符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43143589/