javabyte-buddy

how to use byte-buddy's custom Implementation


how to use byte-buddy's custom 'Implementation' to redefine a method?

long to short, there's a class defined by third party as follows:

class Demo{
    
    public void handle(String value) {
        //....
    }
}

when the method handle called, and i need to check the input and convert it to toLowerCase, the required code as follows:

class Demo{
   
    public void setValue(String value) {
        // code to insert:
        value = value.toLowerCase();
        //....
    }
}

as i know, byte-buddy is the way to achieve it. i normal way is easy, but i need to refine the class, so cannot use MethodDelegation, just modify the method, so how to use custom Implementation to get there, hoping sb can help me!

DynamicType.Loaded<SumExample> loaded = new ByteBuddy()
    .subclass(Demo.class)
    .method(named("setValue"))
    .intercept(MyImplementation.INSTANCE)
    .make()
    .load(Thread.currentThread().getContextClassLoader(), ClassLoadingStrategy.Default.WRAPPER);

    //Implementation to define the method body 
    enum MyImplementation implements Implementation {

        INSTANCE; // singleton

        @Override
        public InstrumentedType prepare(InstrumentedType instrumentedType) {
            return instrumentedType;
        }

        @Override
        public ByteCodeAppender appender(Target implementationTarget) {
            return MyAppender.INSTANCE;
        }

    }
 

   //
   enum MyAppender implements ByteCodeAppender {

        INSTANCE; // singleton

        @Override
        public Size apply(MethodVisitor methodVisitor,
                          Implementation.Context implementationContext,
                          MethodDescription instrumentedMethod) {
            methodVisitor.visitCode();
            // how to write?
            methodVisitor.visitEnd();
            return new Size(0, instrumentedMethod.getStackSize());
        }
    }

Solution

  • You can use Advice to do this, rather than delegation. Advice gives you opportunity to execute code before and after a method. In the enter advice, you'd modify the argument and the original code would be invoked thereafter.