wicket Web beans 学习之BeanMetaData
程序员文章站
2022-07-15 15:18:10
...
介绍:
wicket Web beans(WWB) 是wicket的一个表单制作工具,作用:通过一系列配置,可以直接根据bean的属性,制作表单中的元素,很方便,目前发现一个缺点,form中的样式的定制不是很方面,可能需要进一步的研究wicketwebbean中的代码,才能更好的用好这个工具。
工具的原理其实很简单,下文中介绍的BeanMetaData也是原理中很重要的一个组成部分,这个类主要跟bean对应起来,作为bean的元数据存在,bean中的属性与ElementMetaData这个类对应起来,WWB其实也是通过这些元数据,利用java的反射机制,制成component,然后将所有的component放在container,也就是一个BeanForm中,同意展现出来。刚才说的表单样式的问题,其实工具的提供者考虑了这个问题,工具中的一些标注中,已经提供了样式这个属性,去改变bean属性的样式,虽然这样,但是在样式的使用上,个人觉得不是很方便,直观。下面主要对BeanMetaData这个类进行说明:
关键属性;
private Class<?> beanClass; // 对象类,与bean对应
private Class<?> metaDataClass;
private Beans beansMetaData;
private List<Bean> collectedBeans = new ArrayList<Bean>(); //所有的bean标注的集合
private String context; //通过context可以指定对应的bean,
private Component component;
private ComponentRegistry componentRegistry; //注册bean属性的fieldType
// List of all properties.
private List<ElementMetaData> elements = new ArrayList<ElementMetaData>(); //所有属性和action方法的元数据集合
private List<TabMetaData> tabs = new ArrayList<TabMetaData>(); //tabs元数据的集合
关键方法:
init()
1、 // Check if bean supports PropertyChangeListeners.
2、// Deduce actions from the component.
3、// Create defaults based on the bean itself. (根据BeanMetaData的构造参数,对所有ElementMetaData的viewOnly进行设置)
3.1、bean的属性有属性类型,在构造ElementMetaData对象时,会传入属性类型propertyType
说明:1-3的操作创建元数据的过程,包括bean对象、bean对象下的属性和action方法
下面的步骤涉及到元数据 根据标注进行属性设置:
4、// Collect various sources of metadata for the bean we're interested in.
4.1、collectAnnotations() //收集bean标注(beanClass、metaBeanClass、component)
4.2、collectFromBeanProps(); //Collection Beans from the beanprops file, if any.
4.3、collectBeansAnnotation(beansMetaData, false);
5、// Process action annotations on component.
processActionAnnotation(action, method.getName());
注意点: 1、action如果指定名字必需跟method的一样
2、action中的值都会以参数的形式保存在元数据中
6、// Determine the hierarchy of Bean contexts. I.e., the default Bean is always processed first, followed by those that
// extend it, etc. This acts as a stack.
List<Bean> beansHier = buildContextStack();
Bean标注有context属性,bean标注的propertyName中属性的出现顺序会影响到表单中属性的显示顺序
processBeanAnnotation(bean);
步骤一、将bean的标注属性设置到bean的元数据里面
步骤二、
for (String actionName : bean.actionNames()) {
if (!handleElementRemove(actionName, true)) {
findElementAddPseudos(ACTION_PROPERTY_PREFIX + actionName);
}
}
handleElementRemove : 删除actionName的action元数据
for (Action action : bean.actions()) {
if (!handleElementRemove(action.name(), false)) {
processActionAnnotation(action, null);
}
}
上面代码的逻辑:bean中如果指定了action数组,在element中查找有没有名字相同的action,有则删除,没有则将action的参数设置到对应的元数据中。
processTabAnnotation(Tab tab, TabMetaData tabMetaData) //处理tab标注,作用:创建tab,并为tab中的属性创建元数据,并且标记tabid
现在处理的都是bean标注中的属性
7、// Ensure that if a context was specified, that we found one in the metadata. Otherwise it might have been a typo.
8、// Post-process Bean-level parameters bean元数据的参数为PARAM_DISPLAYED,清楚element和tabs集合
9、// Configure tabs 作用:如果tabs集合为空,则创建一个默认的tab元数据
if (tabs.isEmpty()) {
// Create single default tab.
tabs.add(new TabMetaData(this, DEFAULT_TAB_ID, getParameter(PARAM_LABEL)));
}
String defaultTabId = tabs.get(0).getId();
if (!getBooleanParameter(PARAM_EXPLICIT_ONLY) || defaultTabId.equals(DEFAULT_TAB_ID)) {
// Post-process each property based on bean parameters
for (ElementMetaData elementMeta : elements) {
// If element is not on a tab, add it to the first. If it's an
// action, it must have been assigned an order to
// appear on a tab. Otherwise it is a global action.
if (elementMeta.getTabId() == null
&& (!elementMeta.isAction() || (elementMeta.isAction() && elementMeta
.isActionSpecifiedInProps()))) {
elementMeta.setTabId(defaultTabId);
}
}
}
上面两段代码,将bean对象的属性和action 都放在了默认的tab下面
10、// Remove elements not specified in props 根据 PARAM_EXPLICIT_ONLY 参数 删除没有指定在属性集中的参数
wicket Web beans(WWB) 是wicket的一个表单制作工具,作用:通过一系列配置,可以直接根据bean的属性,制作表单中的元素,很方便,目前发现一个缺点,form中的样式的定制不是很方面,可能需要进一步的研究wicketwebbean中的代码,才能更好的用好这个工具。
工具的原理其实很简单,下文中介绍的BeanMetaData也是原理中很重要的一个组成部分,这个类主要跟bean对应起来,作为bean的元数据存在,bean中的属性与ElementMetaData这个类对应起来,WWB其实也是通过这些元数据,利用java的反射机制,制成component,然后将所有的component放在container,也就是一个BeanForm中,同意展现出来。刚才说的表单样式的问题,其实工具的提供者考虑了这个问题,工具中的一些标注中,已经提供了样式这个属性,去改变bean属性的样式,虽然这样,但是在样式的使用上,个人觉得不是很方便,直观。下面主要对BeanMetaData这个类进行说明:
关键属性;
private Class<?> beanClass; // 对象类,与bean对应
private Class<?> metaDataClass;
private Beans beansMetaData;
private List<Bean> collectedBeans = new ArrayList<Bean>(); //所有的bean标注的集合
private String context; //通过context可以指定对应的bean,
private Component component;
private ComponentRegistry componentRegistry; //注册bean属性的fieldType
// List of all properties.
private List<ElementMetaData> elements = new ArrayList<ElementMetaData>(); //所有属性和action方法的元数据集合
private List<TabMetaData> tabs = new ArrayList<TabMetaData>(); //tabs元数据的集合
关键方法:
init()
1、 // Check if bean supports PropertyChangeListeners.
2、// Deduce actions from the component.
3、// Create defaults based on the bean itself. (根据BeanMetaData的构造参数,对所有ElementMetaData的viewOnly进行设置)
3.1、bean的属性有属性类型,在构造ElementMetaData对象时,会传入属性类型propertyType
说明:1-3的操作创建元数据的过程,包括bean对象、bean对象下的属性和action方法
下面的步骤涉及到元数据 根据标注进行属性设置:
4、// Collect various sources of metadata for the bean we're interested in.
4.1、collectAnnotations() //收集bean标注(beanClass、metaBeanClass、component)
4.2、collectFromBeanProps(); //Collection Beans from the beanprops file, if any.
4.3、collectBeansAnnotation(beansMetaData, false);
5、// Process action annotations on component.
processActionAnnotation(action, method.getName());
注意点: 1、action如果指定名字必需跟method的一样
2、action中的值都会以参数的形式保存在元数据中
6、// Determine the hierarchy of Bean contexts. I.e., the default Bean is always processed first, followed by those that
// extend it, etc. This acts as a stack.
List<Bean> beansHier = buildContextStack();
Bean标注有context属性,bean标注的propertyName中属性的出现顺序会影响到表单中属性的显示顺序
processBeanAnnotation(bean);
步骤一、将bean的标注属性设置到bean的元数据里面
步骤二、
for (String actionName : bean.actionNames()) {
if (!handleElementRemove(actionName, true)) {
findElementAddPseudos(ACTION_PROPERTY_PREFIX + actionName);
}
}
handleElementRemove : 删除actionName的action元数据
for (Action action : bean.actions()) {
if (!handleElementRemove(action.name(), false)) {
processActionAnnotation(action, null);
}
}
上面代码的逻辑:bean中如果指定了action数组,在element中查找有没有名字相同的action,有则删除,没有则将action的参数设置到对应的元数据中。
processTabAnnotation(Tab tab, TabMetaData tabMetaData) //处理tab标注,作用:创建tab,并为tab中的属性创建元数据,并且标记tabid
现在处理的都是bean标注中的属性
7、// Ensure that if a context was specified, that we found one in the metadata. Otherwise it might have been a typo.
8、// Post-process Bean-level parameters bean元数据的参数为PARAM_DISPLAYED,清楚element和tabs集合
9、// Configure tabs 作用:如果tabs集合为空,则创建一个默认的tab元数据
if (tabs.isEmpty()) {
// Create single default tab.
tabs.add(new TabMetaData(this, DEFAULT_TAB_ID, getParameter(PARAM_LABEL)));
}
String defaultTabId = tabs.get(0).getId();
if (!getBooleanParameter(PARAM_EXPLICIT_ONLY) || defaultTabId.equals(DEFAULT_TAB_ID)) {
// Post-process each property based on bean parameters
for (ElementMetaData elementMeta : elements) {
// If element is not on a tab, add it to the first. If it's an
// action, it must have been assigned an order to
// appear on a tab. Otherwise it is a global action.
if (elementMeta.getTabId() == null
&& (!elementMeta.isAction() || (elementMeta.isAction() && elementMeta
.isActionSpecifiedInProps()))) {
elementMeta.setTabId(defaultTabId);
}
}
}
上面两段代码,将bean对象的属性和action 都放在了默认的tab下面
10、// Remove elements not specified in props 根据 PARAM_EXPLICIT_ONLY 参数 删除没有指定在属性集中的参数