Any artifact or class that abides to the following conventions can be registered as an application listener, those conventions are:

- it is a Script, class, Map, RunnableWithArgs or closure.
- in the case of scripts or classes, they must define an event handler whose name matches on<EventName>, this handler can be a method, RunnableWithArgs or a closure property.
- in the case of a Map, each key maps to <EventName>, the value must be a RunnableWithArgs or a closure.
- scripts, classes and maps can be registered/unregistered by calling `addApplicationListener`/ `removeApplicationListener` on the app instance.
- RunnableWithArgs and closure event handlers must be registered with an overloaded version of `addApplicationListener`/`removeApplicationListener` that takes <EventName> as the first parameter, and the runnable/closure itself as the second parameter.

There is a general, per application, script that can provide event handlers. If you want to take advantage of this feature you must define a script named `Events.groovy` inside `griffon-app/conf`. Lastly both Controller and Service instances are automatically registered as application event listeners. This is the only way to declare event listeners for `Log4jConfigStart` and `BootstrapStart` events.

> You can also write a class named `Events.java` in `src/main` as an alternative to `griffon-app/conf/Events.groovy`, but not both!

These are some examples of event handlers:

- Display a message right before default MVC groups are instantiated

`File: griffon-app/conf/Events.groovy`

    onBootstrapEnd = { app ->
      println """Application configuration has finished loading.
    MVC Groups will be initialized now."""
    }

- Quit the application when an uncaught exception is thrown

`File: src/main/Events.java`

    import griffon.util.ApplicationHolder;public class Events {
        public void onUncaughtExceptionThrown(Exception e) {
            ApplicationHolder.getApplication().shutdown();
        }
    }

- Print the name of the application plus a short message when the application is about to shut down.

`File: griffon-app/controller/MyController.groovy`

    class MyController {
      def onShutdownStart = { app ->
        println "${app.config.application.title} is shutting down"
      }
    }

- Print a message every time the event "Foo" is published

`File: griffon-app/controller/MyController.groovy`

    class MyController {
      void mvcGroupInit(Map args) {
        app.addApplicationListener([
          Foo: {-> println 'got foo!' }
        ])
      }  def fooAction = { evt = null ->
        // do something
        app.event('Foo')
      }
    }

- An alternative to the previous example using a closure event handler

`File: griffon-app/controller/MyController.groovy`

    class MyController {
      void mvcGroupInit(Map args) {
        app.addApplicationListener('Foo'){-> println 'got foo!' }
      }  def fooAction = { evt = null ->
        // do something
        app.event('Foo')
      }
    }

- Second alternative to the previous example using a RunnableWithArgs event handler

`File: griffon-app/controller/MyController.java`

    import java.util.Map;
    import griffon.util.RunnableWithArgs;
    import org.codehaus.griffon.runtime.core.AbstractGriffonController;public class MyController extends AbstractGriffonController {
      public void mvcGroupInit(Map<String, Object> params) {
        getApp().addApplicationListener("Foo", new RunnableWithArgs() {
            public void run(Object[] args) {
                System.out.println("got foo!");
            }
        });
      }  public void fooAction() {
        // do something
        getApp().event("Foo");
      }
    }