欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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 Bean