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());
}
}
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.