JSF 2.0: Por que um feijão JSF é criado quando é usado em um componente que não é renderizado?
-
26-09-2019 - |
Pergunta
Vamos ter um componente composto extremamente simples:
<cc:implementation>
#{testBean.someField}
</cc:implementation>
Bean para isso:
public class TestBean {
private boolean someField = false;
public boolean getSomeField() { return someField; }
@PostConstruct
public void init() {
System.out.println("PostConstruct");
}
}
Então chame como de costume, mas não mostre:
<codeEditor:test rendered="#{false}" />
O que acontece é que o componente nunca é renderizado e o feijão nunca é iniciado como seria de se supor.
No entanto, se mudarmos o componente como:
<cc:implementation>
<h:outputText value="#{testBean.someField}" />
</cc:implementation>
O que acontece é que o componente ainda nunca é renderizado (porque o rendered
atributo é false
), no entanto, o feijão é instanciado. Isso sempre acontece quando usamos uma propriedade de feijão dentro de algum componente JSF nativo (h:panelGroup
, h:inputHidden
, qualquer que seja).
Por que é tão?
Solução
Os componentes (e todos os feijões ligados) são criados durante o tempo de construção. O atributo renderizado é avaliado apenas durante o tempo de renderização. Sempre funcionou dessa maneira no JSF.
Se o feijão estiver fazendo um trabalho caro durante a construção, sugiro deixar que esse trabalho caro dependa de algumas condições que você reutiliza no atributo renderizado.