Search code examples
javacode-generationbyte-buddy

How to create a bytebuddy agent that intercepts a field setter from annotated field?


What I am trying to do is basically match a class's field with an annotaion and them intercept the field's getter and setter.

 public class Foo {

    @Sensitive
    private String Blah;

Here is the code for my agent:

    private static AgentBuilder createAgent() {
        return new AgentBuilder
                .Default()
                .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
                .type(ElementMatchers.is(FieldTypeMatcher.class).and(ElementMatchers.isAnnotatedWith(Foo.class)))
                .transform(((builder, typeDescription, classLoader, module) ->
                        builder
                        .method(method -> method.getActualName().contains(typeDescription.getActualName()))
                        .intercept(Advice.to(Interceptor.class))
                ));
    }

I though I could match the field's name with the method's signature but I had no luck.


Solution

  • I assume that Foo has a getter and setter for Blah?

    In this case, I recommend a custom ElementMatcher implementation such as:

    class FieldMatcher implements ElementMatcher<MethodDescription> {
      @Override
      public boolean matches(MethodDescription target) {
        String fieldName;
        if (target.getName().startsWith("set") || target.getName().startsWith("get")) {
          fieldName = target.substring(3, 4).toLowerCase() + target.substring(4);
        } else if (target.getName().startsWith("is")) {
          fieldName = target.substring(2, 3).toLowerCase() + target.substring(3);
        } else {
          return false;
        }
        target.getDeclaringType()
          .getDeclaredFields()
          .filter(named)
          .getOnly()
          .getDeclaredAnnotations()
          .isAnnotationPresent(Sensitive.class);
      }
    }
    

    This matcher checks if a method is a getter or setter, locates the corresponding field and checks for the annotation being present on it.