diff --git a/rest/src/main/java/org/geoserver/rest/DispatcherCallback.java b/rest/src/main/java/org/geoserver/rest/DispatcherCallback.java
new file mode 100644
index 0000000..5fcb935
--- /dev/null
+++ b/rest/src/main/java/org/geoserver/rest/DispatcherCallback.java
@@ -0,0 +1,37 @@
+package org.geoserver.rest;
+
+import org.restlet.Restlet;
+import org.restlet.data.Request;
+import org.restlet.data.Response;
+
+/**
+ * Provides callbacks for the life cycle of a rest request.
+ * 
+ * @author Justin Deoliveira, OpenGeo
+ *
+ */
+public interface DispatcherCallback {
+
+    /**
+     * Called at the start of a request cycle.
+     */
+    void init(Request request, Response response);
+
+    /**
+     * Called once a restlet has been dispatched or routed for a request.
+     */
+    void dispatched(Request request, Response response, Restlet restlet);
+    
+    /**
+     * Called in the event of an exception occurring during a request. 
+     */
+    void exception(Request request, Response response, Restlet restlet, Exception error);
+    
+    /**
+     * Final callback called once a request has been completed. 
+     * <p>
+     * This method is always called, even in the event of an exception during request processing. 
+     * </p>
+     */
+    void finished(Request request, Response response);
+}
diff --git a/rest/src/main/java/org/geoserver/rest/RESTDispatcher.java b/rest/src/main/java/org/geoserver/rest/RESTDispatcher.java
index caad385..a24bc45 100644
--- a/rest/src/main/java/org/geoserver/rest/RESTDispatcher.java
+++ b/rest/src/main/java/org/geoserver/rest/RESTDispatcher.java
@@ -5,6 +5,7 @@
 package org.geoserver.rest;
 
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -52,6 +53,11 @@ public class RESTDispatcher extends AbstractController {
     Router myRouter;
     
     /**
+     * rest request callbacks
+     */
+    List<DispatcherCallback> callbacks;
+    
+    /**
      * geoserver configuration
      */
     GeoServer gs;
@@ -68,6 +74,9 @@ public class RESTDispatcher extends AbstractController {
 
         myConverter = new ServletConverter(getServletContext());
         myConverter.setTarget(createRoot());
+        
+        callbacks = 
+            GeoServerExtensions.extensions(DispatcherCallback.class, getApplicationContext());
     }
 
     protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp)
@@ -137,6 +146,7 @@ public class RESTDispatcher extends AbstractController {
     public Restlet createRoot() {
         if (myRouter == null){
             myRouter = new Router() {
+                
                 @Override
                 protected synchronized void init(Request request,
                         Response response) {
@@ -172,7 +182,20 @@ public class RESTDispatcher extends AbstractController {
                     pageInfo.setExtension( extension );
                     request.getAttributes().put( PageInfo.KEY, pageInfo );
                     
+                    for (DispatcherCallback callback : callbacks) {
+                        callback.init(request, response);
+                    }
                 }
+                
+                public Restlet getNext(Request request, Response response) {
+                    Restlet next = super.getNext(request, response);
+                    if (next != null) {
+                        for (DispatcherCallback callback : callbacks) {
+                            callback.dispatched(request, response, next);
+                        }
+                    }
+                    return next;
+                };
             };
 
             //load all the rest mappings and register them with the router
