Alex Rivera | Logout

Custom annotation as Interceptor for a method logging

Asked 2012-08-26T13:49:18.280
44

Java Gurus,

I am pretty new for annotations and haven't searched for this a lot, so please bear with me...

I would like to implement a Custom Annotation which will intercept a method call; to start with something very basic it can just print the methods name and parameters so that I could avoid the logger statement.

A sample call like this:

public MyAppObject findMyAppObjectById(Long id) throws MyCustomException {
    log.debug("in findMyAppObjectById(" + id + ")");
    //....
}   

can be converted into:

@LogMethodCall(Logger.DEBUG)
public MyAppObject findMyAppObjectById(Long id) throws MyCustomException {
    //....
}   

Could I get some hints about this?

Edit
Report

1 Answer

49

Based in your answers of my comments, you will not be able to do this with just annotations. You can, of course, create your annotations and create some reflective code that will detected then and execute some code, but this will not change your code too much, because you will need to call the parser method before you call your methods and I think that will not help you too much, since you will need to call the parser method before each call.

If you need the behavior that you mentioned (automatic call), you will need to combine your annotations with some AOP framework like Spring (plain Java) or AspectJ (AspectJ code). With then, you can set pointcuts and everytime this point is reached, some code may be executed. You can configure then to execute some code before and/or after method execution.

If the first scenario is sufficient, you can do something like:

Logger: enum

public enum Logger {
    INFO,
    DEBUG;
}

LogMethodCall: annotation

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention( RetentionPolicy.RUNTIME ) // the annotation will be available during runtime
@Target( ElementType.METHOD )         // this can just be used in methods
public @interface LogMethodCall {

    Logger logLevel() default Logger.INFO;

}

Person: annotated class

public class Person {

    // will use the default log level (INFO)
    @LogMethodCall
    public void foo( int a ) {
        System.out.println( "foo! " + a );
    }

    @LogMethodCall( logLevel = Logger.DEBUG )
    public void bar( int b ) {
        System.out.println( "bar! " + b );
    }

}

Utils: class with the log static method (this will perform the "

answered 2012-08-26T14:24:51.630

Your Answer