Ulisse
Ulisse

Reputation: 483

Jersey and AOP without Spring

I am using Grizzly with Jersey 2.1. I would like to add an aspect for logging purpose (before and after each method execution). Is it possibile to do this without using Spring or Google-Guice?

Thanks

Upvotes: 2

Views: 3342

Answers (1)

Michal Gajdos
Michal Gajdos

Reputation: 10379

You can achieve something very similar by using monitoring features offered by Jersey (particularly via event listeners). Basically you need to create and register an instance of ApplicationEventListener and RequestEventListener where you would be listening to RESOURCE_METHOD_START and RESOURCE_METHOD_FINISHED events.

@Provider
public class MyApplicationEventListener implements ApplicationEventListener {

    @Override
    public void onEvent(ApplicationEvent event) {
        // NOOP.
    }

    @Override
    public RequestEventListener onRequest(RequestEvent requestEvent) {
        return new RequestEventListener() {

            @Override
            public void onEvent(final RequestEvent event) {
                switch (event.getType()) {
                    case RESOURCE_METHOD_START:
                        logMethod(event.getUriInfo(), true);
                        break;

                    case RESOURCE_METHOD_FINISHED:
                        logMethod(event.getUriInfo(), false);
                        break;
                }
            }

            private void logMethod(final ExtendedUriInfo uriInfo, final boolean entering) {
                final Class<?> resource = uriInfo
                        .getMatchedResources().get(0).getClass();

                final Method method = uriInfo
                        .getMatchedResourceMethod()
                        .getInvocable()
                        .getHandlingMethod();

                if (entering) {
                    logger.entering(resource.toString(), method.toString());
                } else {
                    logger.exiting(resource.toString(), method.toString());
                }
            }
        };
    }
}

Register the listener into your application:

public class MyApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        final HashSet<Class<?>> classes = new HashSet<Class<?>>();

        // Add root resources.
        classes.add(HelloWorldResource.class);
        
        // Add ApplicationEventListener.
        classes.add(MyApplicationEventListener.class);
        
        return classes;
    }
}

NOTE: These events are fired only around a resource method "to-be-executed" and not for sub-resource locators that might be executed during resource matching phase.


EDIT 1

To log each invoked method (even methods invoked from a JAX-RS resource method) refer to the AspectJ project.

Upvotes: 4

Related Questions