To declare a listener, you have to add the listener element to zk.xml. You could specify any number of listener elements. Each of them could have two child elements, description and listener-class, where description is optional.
<zk> <listener> <listener-class>my.MyInit</listener-class> </listener> </zk>
The type of a listener depends on what interface it implements. For example, if a listener implements the org.zkoss.zk.ui.event.EventThreadInit interface, then it is used to listen when an event processing thread is initialized. A listener could implement multiple interfaces and it will be used whenever the corresponding interface is about to call.
It is implemented by a listener class that will be used to initialize an event processing thread, before an event is dispatched to it for processing.
If a listener implements this interface, an instance is created, and then the prepare method is called in the main thread (aka., the servlet thread), before processing an event. Then, the init method is called in the event processing thread.
If a developer wants to prevent an event from being processed, he can throw an exception in the prepare method or the init method.
A typical use of this feature is to implement auto-authentication. For example, JBoss[7] required you to call SecurityAssociation.setPrincipal to grant permissions of a user to the event processing thread, as described in the Initialization Before Processing Each Event section, the Event Listening and Processing chapter.
It is implemented by a listener class that will be used to cleanup an event processing thread, after it has processed an event.
If a listener implements this interface, an instance is created, and then the cleanup method is called in the event processing thread after the thread processes the event. Then, the complete method is called in the main thread (aka., the servlet thread), after the main thread is resumed.
Note: The complete method won't be called if the corresponding cleanup method threw an exception.
A typical use of this feature is to clean up unclosed transaction.
Once registered, an instance is constructed and the cleanup method is called after leaving the event processing thread.
It is implemented by a listener class that will be called before an event processing thread is going to be suspended.
If a listener implements this interface, an instance is created, and then the beforeSuspend method, when an event processing thread is going to suspended. It executes in the event processing thread.
A developer can prevent can prevent an event processing thread from being suspended by throwing an exception.
A typical use of this feature is to limit the number of suspended threads.
It is implemented by a listener class that will be called after an event processing thread is resumed or aborted.
If a listener implements this interface, an instance is created, and then the beforeResume method is called in the main thread (aka., the servlet thread), when a suspended event thread is being resumed. Then, the afterResume method is called in the event processing thread after the thread is resumed successfully.
If a developer wants to prevent an event from being resumed, he can throw an exception in the beforeResume method.
Notice that beforeResume executes in the main thread, so it shares the same thread-local storage with the main thread. On the other hand, afterResume executes in the event processing thread, so it shares the same thread-local storage with the event thread (and application event listeners).
In additions to resuming normally, a suspended event processing thread might be aborted abnormally. For example, when the desktop is being destroyed, all suspended event threads will be aborted. When the suspended event processing thread is aborted, an instance is created, and the abortResume method is called in the main thread.
Note: If a suspended event thread is aborted, none of the beforeResume and afterResume is called. Moreover, the cleanup and complete methods of EventThreadCleanup won't be called, either. Thus, you have to handle all necessary cleanups in abortResume.
It is implemented by a listener class that will be used to intercept when an event is sent, posted and processed.
Like other configurations, the event interceptors registered here are application-wide. It means they will intercept all events for the whole application. If you want to intercept events only for a particular desktop, use the addEventInterceptor method of the org.zkoss.zk.ui.Desktop interface.
It is implemented by a listener class that will be used to initialize a ZK application.
When a ZK application is created, it invokes the init method of this interface such that developers could plug the application-specific codes to initialize the application.
It is implemented by a listener class that will be used to cleanup a ZK application that is being destroyed.
When a ZK application is going to be destroyed, it invokes the cleanup method of this interface such that developers could plug the application-specific codes to cleanup the application.
It is implemented by a listener class that will be used to initialize a new session.
When ZK Loader created a new session, it invokes the init method of this interface such that developers could plug the application-specific codes to initialize a session.
A developer can prevent a session from being created by throwing an exception in the init method.
It is implemented by a listener class that will be used to cleanup a session that is being destroyed.
When ZK Loader is going to destroy a session, it invokes the cleanup method of this interface such that developers could plug the application-specific codes to cleanup a session.
It is implemented by a listener class that will be used to initialize a new desktop.
When ZK Loader created a new desktop, it invokes the init method of this interface such that developers could plug the application-specific codes to initialize a desktop.
A developer can prevent a desktop from being created by throwing an exception in the init method.
It is implemented by a listener class that will be used to cleanup a desktop that is being destroyed.
When ZK Loader is going to destroy a desktop, it invokes the cleanup method of this interface such that developers could plug the application-specific codes to cleanup a desktop.
It is implemented by a listener class that will be used to initialize a new execution.
When ZK Loader and Update Engine created a new execution, it invokes the init method of this interface such that developers could plug the application-specific codes to initialize an execution.
Tip: Executions might be stacked. To know whether it is the first execution since a (Servlet) request is processed, you can check whether the parent argument is null.
A developer can prevent an execution from being created by throwing an exception in the init method.
It is implemented by a listener class that will be used to cleanup an execution that is being destroyed.
When ZK Loader is going to destroy an execution, it invokes the cleanup method of this interface such that developers could plug the application-specific codes to cleanup an execution.
It is implemented by a listener class that will be used to intercept the retrieving of ZUML pages with the associated URI. Once registered, an instance of the specified class is created, and then the request method is invoked, each time the application wants to retrieve the page definition of a page based on an URI.
A typical use of this interface is to ensure the current user has the authority to access the certain URI.
You can register any number of URI interceptors (URIInterceptor).
Note:
Unlike ExecutionInit and many other listeners, an instance of the registered URIInterceptor is created at the time of registration, and then it is shared by the whole application. Thus, you have to make sure it can be accessed concurrently.
It is implemented by a listener class that will be used to intercept each request made to ZK Loader and ZK Update Engine. Once registered, an instance of the specified class is created, and then the request method is invoked, each time a request is received by ZK Loader or ZK Update Engine.
A typical use of this interface is to determine the locale and/or time zone of the request. Refer to the Developer's Guide for more information.
You can register any number of the request interceptors (RequestInterceptor).
Note:
Unlike ExecutionInit and many other listeners, an instance of the registered RequestInterceptor is created at the time of registration, and then it is shared by the whole application. Thus, you have to make sure it can be accessed concurrently.
The request parameters will be parsed with the proper locale and character encoding, after the request method is called. It is not recommended to call the getParameter or getParameterValues methods (of javax.servlet.ServletRequest) in this method.
It is implemented by a listener that will measure the performance. Unlike other listeners, there is at most one performance meter listener for each Web application. If you like, you can chain them together manually.
It is implemented by a listener that will be used to monitor the statuses of ZK. Unlike other listener, there is at most one monitor listener for each Web application. If you like, you can chain them together manually.
ZK provides an implementation named org.zkoss.zk.ui.util.Statistic, which accumulates the statistic data in the memory. It is a good starting point to understand the load of your ZK application.