ОБНОВЛЕНИЕ:
Жизненные циклы любых компонентов @ViewScoped
и @SessionScoped
не соответствуют ожидаемым. То есть они заканчиваются раньше, чем должны. Например, когда выполняется обратная передача ajax, когда метод возвращает void, ни @ViewScoped
, ни @SessionScoped
bean-компоненты не должны заканчиваться, но они заканчиваются.
После развертывания его в нашей среде разработки и других тестирующих его, кажется, что это происходит только на моей машине и при локальном запуске. Не знаю, почему. tc Server 3.1 используется.
Я оставляю оригинал на случай, если кто-то столкнется с проблемой аналогично.
Оригинал:
У меня есть дерево, заполненное ViewScoped, которое считывает данные из XML-файла и создает для него объекты TreeNode. Производительность не очень быстрая, поэтому идеален тот факт, что он создается в представлении один раз. (Некоторые части кода были опущены ниже, хотя функциональность работает)
@ManagedBean
@ViewScoped
public class FundsXmlTreeBuilder implements Serializable {
private TreeNode root;
public FundsXmlTreeBuilder() throws SAXException, IOException, ParserConfigurationException {
root = new DefaultTreeNode("Root", null);
buildTree();
}
public void buildTree() throws SAXException, IOException, ParserConfigurationException {
//reads xml file and adds TreeNodes
}
}
Существует еще один bean-компонент RequestScoped, у которого есть метод, обрабатывающий ajax-событие узла дерева, выбранного в методе onNodeSelect. Он в основном определяет, как будет отображаться другая часть страницы.
@ManagedBean
@RequestScoped
public class FundsXmlDisplay implements Serializable{
private Fund fund;
private FundFamily fundFamily;
private FocusedPortfolioModel model;
public TreeNode selectedRoot;
public FundsXmlDisplay() {
fund = null;
fundFamily = null;
model = null;
selectedRoot = null;
}
public void onNodeSelect(NodeSelectEvent event) {
Object data = event.getTreeNode().getData();
fund = null;
fundFamily = null;
model = null;
if (data instanceof Fund) {
fund = (Fund) data;
} else if (data instanceof FundFamily) {
fundFamily = (FundFamily) data;
} else if (data instanceof FocusedPortfolioModel) {
model = (FocusedPortfolioModel) data;
model.createPieModel();
}
}
}
Вот основные части разметки.
<h:body>
<h:form styleClass="form" id="form1">
*** For Home Office Use Only
<br />
<p:layout id="xmlArea"
style="min-width:400px;min-height:600px;width:95%;">
<p:layoutUnit id="xmlTree" position="west" resizable="false"
closable="false" scrollable="true" size="25%" minSize="40"
maxSize="400" style="padding:.25em;" header="Funds XML Elements">
<p:tree value="#{fundsXmlTreeBuilder.root}" var="node"
dynamic="false" selectionMode="single">
<p:ajax event="select" update=":form1:xmlDisplay"
listener="#{fundsXmlDisplay.onNodeSelect}" />
<p:treeNode>
<h:outputText value="#{node}" style="font-size:small" />
</p:treeNode>
</p:tree>
</p:layoutUnit>
<p:layoutUnit position="center" header="Element Detail" size="75%">
<p:scrollPanel id="xmlDisplay" mode="native"
style="height:100%;">
...
</p:scrollPanel>
</p:layoutUnit>
</p:layout>
</h:form>
</h:body>
Проблема, с которой я сталкиваюсь, заключается в том, что FundsXmlTreeBuilder воссоздается после запуска события ajax, но перед прослушивателем. Я бы ожидал, что он вообще не будет воссоздан, поскольку, насколько я понимаю, вид не меняется.
В области xmlDisplay довольно много отображаемых атрибутов. Не уверен, что это актуально. Я понимаю, что представление живет, когда метод действия возвращает null или void, но я не думаю, что используемые визуализированные методы считаются «методами действия».
Что также интересно, если я изменю FundsXmlTreebuilder на SessionScoped, он будет воссоздан и после выбора узла, что действительно поставило меня в тупик.
Надеюсь, все понятно и информации достаточно. Спасибо!
@PostConstruct
аннотированный метод. Ищите дубликат в SO, он существует - person Kukeltje   schedule 20.01.2016@PostConstruct
, но этот метод никогда не вызывался. Я чувствую, что это может быть связано с тем, что бобы неожиданно воссоздаются локально. - person cfreih   schedule 20.01.2016