Why is the getter called so many times by the rendered attribute?

前端 未结 2 1947
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-30 09:47

Related to a previous example, i tried to monitor my get/set methods on the server (when they are called, and how often). So, my actual been look such :

@Man         


        
相关标签:
2条回答
  • 2020-11-30 10:23

    you can use CDI Producers methods. It will be called many times, but the result of first call is cached in scope of the bean and is efficient for getters that are computing or initializing heavy objects! See here, for more info.

    0 讨论(0)
  • 2020-11-30 10:33

    EL (Expression Language, those #{} things) won't cache the result of the calls or so. It just accesses the data straight in the bean. This does normally not harm if the getter just returns the data.

    The setter call is done by @ManagedProperty. It basically does the following:

    selector.setProfilePage(request.getParameter("profilePage"));
    

    The getter calls are all done by rendered="#{selector.profilePage == 'some'}" during the render response phase. When it evaluates false the first time, in UIComponent#encodeAll(), then no more calls will be done. When it evaluates true, then it will be re-evaluated six more times in the following sequence:

    1. UIComponent#encodeBegin() - Locates renderer for the begin of component.
    2. Renderer#encodeBegin() - Renders begin of component.
    3. UIComponent#encodeChildren() - Locates renderer for children of component.
    4. Renderer#encodeChildren() - Renders children of component.
    5. UIComponent#encodeEnd() - Locates renderer for end of component.
    6. Renderer#encodeEnd() - Renders end of component.

    The component and its renderer verifies during every step if it is allowed to render. During a form submit, if an input or command component or any of its parents has a rendered attribute, then it will also be evaluated during apply request values phase as part of safeguard against tampered/hacked requests.

    True, this look like clumsy and inefficient. It was considered the achilles heal of JSF as per spec issue 941. It's been suggested to remove all those repeated checks and stick to the one done in UIComponent#encodeAll(), or to evaluate isRendered() on a per-phase basis. During EG discussion, it became clear the root of the problem is in EL, not in JSF, and that performance could be greatly improved with CDI. So there was no necessity to solve it from JSF spec side on.


    If your concern is that the managed property should be checked only once after its setting if it's null or empty, then consider to move it into a method which is annotated with @PostConstruct. Such a method will be called directly after bean's construction and all dependency injection.

    @PostConstruct
    public void init() {
        if (profilePage == null || profilePage.trim().isEmpty()) {
            profilePage = "main";
        }
    }
    

    See also:

    • Why JSF calls getters multiple times?
    0 讨论(0)
提交回复
热议问题