如何创建复合组件的实例以及如何获取它

How is an instance of composite component created and how can I get it

我正在使用 Mojarra 2.1。阅读 this 关于何时使用自定义标签和复合组件的回答,我遇到了有关组件内部结构的问题。

因此,自定义标签和复合组件之间最重要的区别是每个复合组件都有一个 UIComponent 实例,在 查看构建时间 [=34] 之后在组件树中表示它=] 完成了。自定义标签反过来在树中没有一个 UIComponent 实例代表它。

那么,class 代表树中的复合组件是什么?它是如何创建的?那是一些匿名的 class 吗?让我们考虑来自 wiki 页面的示例:

    <ui:component
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:cc="http://java.sun.com/jsf/composite"
>
    <cc:interface>
        <!-- Define component attributes here -->
    </cc:interface>
    <cc:implementation>
        <!-- Define component body here -->
    </cc:implementation>
</ui:component>

如何获取代表该复合组件的 UIComponent 的实例?

深入研究 UIComponent 的源代码,我发现了以下方法:

public static boolean isCompositeComponent(UIComponent component) {

        if (component == null) {
            throw new NullPointerException();
        }
        boolean result = false;
        if (null != component.isCompositeComponent) {
            result = component.isCompositeComponent.booleanValue();
        } else {
            result = component.isCompositeComponent =
                    (component.getAttributes().containsKey(
                               Resource.COMPONENT_RESOURCE_KEY));
        }
        return result;

    }

我怀疑它的实现详细说明了如何创建复合组件 class。事实上,我想找到 Mojarra 实现在哪里生成复合组件 class 实例。

UPD:复合组件的定义已替换为未明确定义 componentType 属性的定义。

基本上是UIPanel instance which you can just get via UIComponent#findComponent() the usual way, passing the composite component client ID. In case of Mojarra, you can find the code responsible for creating it in com.sun.faces.facelets.tag.jsf.CompositeComponentTagHandler which has in Mojarra 2.2.11下面的逻辑:

360        if (ComponentHandler.isNew(c)) {
361            facetComponent = (UIPanel)
362            facesContext.getApplication().createComponent("javax.faces.Panel");
363            facetComponent.setRendererType("javax.faces.Group");
364            c.getFacets().put(UIComponent.COMPOSITE_FACET_NAME, facetComponent);
365        }                                                                                 
366        else {
367            facetComponent = (UIPanel) 
368                    c.getFacets().get(UIComponent.COMPOSITE_FACET_NAME);
369        }