6

In my Java EE program I want to use Interceptor for logging purpose. It's easy to use when I'm entering a method :

The annotation :

@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({ METHOD, TYPE })
public @interface Logged {

}

The interceptor :

@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    private Logger logger;

    @AroundInvoke
    public Object logMethodEntry(InvocationContext invocationContext) throws Exception {

        logger.info("Entering method: "
            + invocationContext.getMethod().getName() + " in class "
            + invocationContext.getMethod().getDeclaringClass().getName());

        return invocationContext.proceed();

    }
}

My class using the interceptor :

public class MyClass {

    @Logged
    public void MyMethod() {
        // do something
    }

}

But now I want to do same thing when I'm leaving MyMethod. Is that possible ?

2 Answers 2

8

AroundInvoke does not imply specifically entering - it implies that you hang it "around the invocation"; its name is aptly chosen. That proceed() call that is in there is the actual method invocation you are wrapping with the interceptor. As such you currently log BEFORE the proceed() call - if you add a log AFTER the proceed() invocation, that is the point of leaving the method invocation.

@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {

  private static final long serialVersionUID = 1L;

  @Inject
  private Logger logger;

  @AroundInvoke
  public Object logMethodCall(InvocationContext invocationContext) throws Exception {

        logger.info("Entering method: "
          + invocationContext.getMethod().getName() + " in class "
          + invocationContext.getMethod().getDeclaringClass().getName());

        Object ret = invocationContext.proceed();

        logger.info("Left method: "
          + invocationContext.getMethod().getName() + " in class "
          + invocationContext.getMethod().getDeclaringClass().getName());

        return ret;
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

In this code, how do I get the response of the main function after invocationContext.proceed() successfully
4

@Gimby answer is almost correct. What's missing from his solution is the exception handling. In case of exception the "Left method" is never logged.

Suggestet solution:

@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {

  private static final long serialVersionUID = 1L;

  @Inject
  private Logger logger;

  @AroundInvoke
  public Object logMethodCall(InvocationContext invocationContext) throws Exception {

        Object ret = null;
        logger.info("Entering method: "
          + invocationContext.getMethod().getName() + " in class "
          + invocationContext.getMethod().getDeclaringClass().getName());

        try {

           ret = invocationContext.proceed();

        } catch(Exception e) {

            throw e;

        } finally  {

           logger.info("Left method: "
             + invocationContext.getMethod().getName() + " in class "
             + invocationContext.getMethod().getDeclaringClass().getName());

        }

        return ret;
  }
}

1 Comment

This code won't compile because ret is not in scope

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.