简体   繁体   中英

Using Java annotations to generate some code within a method

I would annotate a Java method in order to run some code before the method body is executed and before the method returns to the caller. I read about code generation at compile time using Java annotation.

The signature of the method I would annotate is as in the following example.

public Output process(Input arg0) {
    // ...
    // body that creates output object as processing result of arg0
    // ...
    return output;
}

I would annotate the above method in order to log the input argument before the method body is executed and to log the output data before the method returns to the caller.

I hypothesized an annotation like the following one.

@Log(input = "arg0", inputDest = "log1.txt", outputDest = "log2.txt")

The above annotation should generate (at compile time) some code like the following.

public Output process(Input arg0) {
    SampleLogger.log(arg0, "log1.txt");   // <-- generated code
    // ...
    // body that creates Output object as processing result of arg0
    // ...
    SampleLogger.log(output, "log2.txt");   // <-- generated code
    return output;
}

How to achieve this?

Yes, you can. But you should not use compile code generation. As the comment above mentioned, project lombok do such genration in compile period. But it is trick. It uses so many private API which let the project complex and hard to maintain.

What you really need is to enter into the method invocation so that you can enhance the method implematation. That is what AOP do.

For your requirenemnt, there are many libraries can do it. Such as Cglib , AspectJ , Spring AOP . Here give you a simple Cglib sample

  public static void main(String[] arg) {
    YourClass actualInstance = new YourClass();
    YourClass instanceToUse = (YourClass) Enhancer.create(YourClass.class, (MethodInterceptor) (obj, method, args, proxy) -> {
      System.out.println("enter the method: " + method.getName());
      Object result = method.invoke(actualInstance, args);
      System.out.println("exit the method: " + method.getName());
      return result;
    });
    instanceToUse.process();
  }

  public static class YourClass {
    public Object process() {
      System.out.println("do something");
      return new Object();
    }
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM