你可以做到這一點與自定義ViewDeclarationLanguage
,讓你測量createView()
,buildView()
,renderView()
並在必要時restoreView()
方法。
這裏有一個開球例如:
public class VdlLogger extends ViewDeclarationLanguageWrapper {
private static final Logger logger = Logger.getLogger(VdlLoggerFactory.class.getName());
private ViewDeclarationLanguage wrapped;
public VdlLogger(ViewDeclarationLanguage wrapped) {
this.wrapped = wrapped;
}
@Override
public UIViewRoot createView(FacesContext context, String viewId) {
long start = System.nanoTime();
UIViewRoot view = super.createView(context, viewId);
long end = System.nanoTime();
logger.info(String.format("create %s: %.6fms", viewId, (end - start)/1e6));
return view;
}
@Override
public void buildView(FacesContext context, UIViewRoot view) throws IOException {
long start = System.nanoTime();
super.buildView(context, view);
long end = System.nanoTime();
logger.info(String.format("build %s: %.6fms", view.getViewId(), (end - start)/1e6));
}
@Override
public void renderView(FacesContext context, UIViewRoot view) throws IOException {
long start = System.nanoTime();
super.renderView(context, view);
long end = System.nanoTime();
logger.info(String.format("render %s: %.6fms", view.getViewId(), (end - start)/1e6));
}
@Override
public ViewDeclarationLanguage getWrapped() {
return wrapped;
}
}
讓它運行,創建下面的工廠:
public class VdlLoggerFactory extends ViewDeclarationLanguageFactory {
private ViewDeclarationLanguageFactory wrapped;
public VdlLoggerFactory(ViewDeclarationLanguageFactory wrapped) {
this.wrapped = wrapped;
}
@Override
public ViewDeclarationLanguage getViewDeclarationLanguage(String viewId) {
return new VdlLogger(wrapped.getViewDeclarationLanguage(viewId));
}
@Override
public ViewDeclarationLanguageFactory getWrapped() {
return wrapped;
}
}
而且在faces-config.xml
如下注冊它:
<factory>
<view-declaration-language-factory>com.example.VdlLoggerFactory</view-declaration-language-factory>
</factory>
的createView()
是創建具體UIViewRoot
實例ba的步驟sed <f:view>
和<f:metadata>
存在於視圖文件中。當使用Facelets(XHTML)作爲視圖時,在此步驟中,所有關聯的XHTML文件將由SAX解析器解析並緩存一段時間,如javax.faces.FACELETS_REFRESH_PERIOD
中所定義。所以可能會發生這樣的情況,一段時間相對較慢,另一段時間很快。
buildView()
是基於視圖(XHTML)組合填充JSF組件樹(getChildren()
的)的步驟。在此步驟中,將執行所有標記處理程序(JSTL和朋友),並評估這些標記處理程序和組件的id
和binding
屬性中的所有EL表達式(有關詳細信息,另請參閱JSTL in JSF2 Facelets... makes sense?)。因此,如果在查看構建時間期間第一次構建支持bean並在@PostConstruct
期間調用業務邏輯時,可能會發生這種情況,這很耗時。
renderView()
是基於JSF組件樹和模型生成HTML輸出的步驟,從UIViewRoot#encodeAll()
開始。因此,如果在查看渲染時間期間第一次構建支持bean並在@PostConstruct
期間調用業務邏輯時,可能會發生這種情況,這很耗時。
如果支持bean在getter方法中而不是在@PostConstruct
或任何其他一次性生命週期事件偵聽器中錯誤地執行業務邏輯,則可能會發生這種情況,這會消耗更多時間。另見Why JSF calls getters multiple times。
這只是...真棒。謝謝! – user2271933
不客氣。在2.2中添加了 – BalusC
[ViewDeclarationLanguageWrapper](http://docs.oracle.com/javaee/7/api/javax/faces/view/ViewDeclarationLanguageWrapper.html)。你認爲修改這個版本可以很容易地與2.1一起工作,還是我會更好地尋找另一種實現它的方式? –