Sie können mit einem benutzerdefinierten ViewDeclarationLanguage
tun, wobei Sie die createView()
messen, buildView()
, renderView()
und ggf. restoreView()
Methoden.
Hier ist ein Kick-off Beispiel:
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;
}
}
und registrieren Sie es wie unten in faces-config.xml
:
<factory>
<view-declaration-language-factory>com.example.VdlLoggerFactory</view-declaration-language-factory>
</factory>
Die
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;
}
}
Um den unten Fabrik zu erhalten zu laufen, erstellen createView()
ist der Schritt zum Erstellen der Beton UIViewRoot
Instanz ba sed auf <f:view>
und <f:metadata>
in den Ansichtsdateien vorhanden. Bei der Verwendung von Facelets (XHTML) als Ansicht werden während dieses Schritts alle zugeordneten XHTML-Dateien vom SAX-Parser analysiert und für eine Zeit zwischengespeichert, die in javax.faces.FACELETS_REFRESH_PERIOD
definiert ist. So kann es passieren, dass es einmal relativ langsam und das andere Mal blitzschnell ist.
Die buildView()
ist der Schritt der JSF Komponentenbaum Bevölkern (der getChildren()
von UIViewRoot
), basierend auf der Ansicht (XHTML) Zusammensetzung. Während dieses Schritts werden alle Taghandler (JSTL und Freunde) ausgeführt und alle EL-Ausdrücke in diesen Taghandlern und Komponenten id
und binding
Attribute ausgewertet (für Details, siehe auch JSTL in JSF2 Facelets... makes sense?). Wenn Backing-Beans also zum ersten Mal während der Erstellung der Ansicht erstellt werden und während die Geschäftslogik aufgerufen wird, kann dies zeitaufwendig sein.
Die renderView()
ist der Schritt zum Generieren der HTML-Ausgabe basierend auf JSF-Komponentenbaum und das Modell, beginnend mit UIViewRoot#encodeAll()
. Wenn Backing-Beans also zum ersten Mal während der Renderzeit der Ansicht erstellt werden und während die Geschäftslogik aufgerufen wird, kann dies zeitaufwendig sein.
Wenn Backing-Beans die Geschäftslogik in Getter-Methoden anstelle von oder einem anderen einmalig vorkommenden Lebenszyklus-Ereignis-Listener falsch ausführen, kann dies dazu führen, dass dies noch mehr Zeit in Anspruch nimmt. Siehe auch Why JSF calls getters multiple times.
Das ist einfach ... großartig. Vielen Dank! – user2271933
Gern geschehen. – BalusC
[ViewDeclarationLanguageWrapper] (http://docs.oracle.com/javaee/7/api/javax/faces/view/ViewDeclarationLanguageWrapper.html) wurde in 2.2 hinzugefügt. Denkst du, es wäre einfach, dies zu modifizieren, um mit 2.1 zu arbeiten, oder würde ich besser nach einer anderen Möglichkeit suchen, es zu implementieren? –