2012-03-02 54 views
1

我正在尋找一種方法來測量我的JSF應用程序中所有操作的執行時間。如何測量JSF中的動作執行時間?

哈克解決方案,我發現到目前爲止是延長com.sun.faces.application.ActionListenerImpl,覆蓋的processAction,並調用super.processAction我在執行:

public class MyActionListener extends ActionListenerImpl { 

      public void processAction(ActionEvent event) throws FacesException { 
        watch.start(); 
        super.processAction(event); 
        watch.stop(); 
      } 
} 

然後我將我自己的ActionListener實現添加到faces配置:

<application> 
     <action-listener>MyActionListener</action-listener> 
</application 

但是這增加了對jsf-impl的依賴並且是hacky。有更好的解決方案嗎?

回答

0

是最好的工作是實現一個ServletContextListener來,實現contextInitialized,創建當前默認的動作偵聽器的反射代理,並測量代理的調用處理程序時的解決方案。

@Override 
    public void contextInitialized(ServletContextEvent sce) { 
     // get JSF application factory 
     ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY); 
     Application application = applicationFactory.getApplication(); 
     ActionListener defaultActionListener = application.getActionListener(); 

     // create proxy for the default actionlistener 
     ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); 
     ActionListenerInvocationHandler actionListenerInvocationHandler = new ActionListenerInvocationHandler(defaultActionListener); 
     @SuppressWarnings("rawtypes") 
     Class[] interfaces = new Class[] { ActionListener.class }; 
     ActionListener actionListenerProxy = (ActionListener) Proxy.newProxyInstance(contextClassLoader, interfaces, actionListenerInvocationHandler); 

     // set proxied actionListener as new default actionlistener 
     application.setActionListener(actionListenerProxy); 

    } 
2

你可以使用一個PhaseListener來代替,而勾上PhaseId.INVOKE_APPLICATION

public class MyPhaseListener implements PhaseListener { 

    public PhaseId getPhaseId() { 
     return PhaseId.INVOKE_APPLICATION; 
    } 

    public void beforePhase(PhaseEvent event) { 
     watch.start(); 
    } 

    public void afterPhase(PhaseEvent event) { 
     watch.stop(); 
    } 

} 

登記爲<phase-listener>代替。

請注意,我知道您的代碼是僞代碼,但爲了完整起見,我想警告您,您需要認識到,所有線程/請求之間共享同一個偵聽器實例。您更希望將watch存儲在請求映射中,絕對不是實例變量。