友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

定制化仪表

1
2
3
4
LDC     10  // stack contains 10
LDC     50  // stack contains 10, 50
IADD        // stack contains 60
IRETURN     // stack is empty
1
2
3
4
12 00 01
12 00 02
60
AC
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
enum IntegerSum implements StackManipulation {

  INSTANCE; // singleton

  @Override
  public boolean isValid() {
    return true;
  }

  @Override
  public Size apply(MethodVisitor methodVisitor,
                    Implementation.Context implementationContext) {
    methodVisitor.visitInsn(Opcodes.IADD);
    return new Size(-1, 0);
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
enum SumMethod implements ByteCodeAppender {

  INSTANCE; // singleton

  @Override
  public Size apply(MethodVisitor methodVisitor,
                    Implementation.Context implementationContext,
                    MethodDescription instrumentedMethod) {
    if (!instrumentedMethod.getReturnType().asErasure().represents(int.class)) {
      throw new IllegalArgumentException(instrumentedMethod + " must return int");
    }
    StackManipulation.Size operandStackSize = new StackManipulation.Compound(
      IntegerConstant.forValue(10),
      IntegerConstant.forValue(50),
      IntegerSum.INSTANCE,
      MethodReturn.INTEGER
    ).apply(methodVisitor, implementationContext);
    return new Size(operandStackSize.getMaximalSize(),
                    instrumentedMethod.getStackSize());
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
enum SumImplementation implements Implementation {

  INSTANCE; // singleton

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

  @Override
  public ByteCodeAppender appender(Target implementationTarget) {
    return SumMethod.INSTANCE;
  }
}
1
2
3
4
5
6
7
8
9
abstract class SumExample {
  public abstract int calculate();
}

new ByteBuddy()
  .subclass(SumExample.class)
    .method(named("calculate"))
    .intercept(SumImplementation.INSTANCE)
  .make()

创建自定义分配器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
enum ToStringAssigner implements Assigner {

  INSTANCE; // singleton

  @Override
  public StackManipulation assign(TypeDescription.Generic source,
                                  TypeDescription.Generic target,
                                  Assigner.Typing typing) {
    if (!source.isPrimitive() && target.represents(String.class)) {
      MethodDescription toStringMethod = new TypeDescription.ForLoadedType(Object.class)
        .getDeclaredMethods()
        .filter(named("toString"))
        .getOnly();
      return MethodInvocation.invoke(toStringMethod).virtual(sourceType);
    } else {
      return StackManipulation.Illegal.INSTANCE;
    }
  }
}
1
2
3
4
5
6
7
new ByteBuddy()
  .subclass(Object.class)
  .method(named("toString"))
    .intercept(FixedValue.value(42)
      .withAssigner(new PrimitiveTypeAwareAssigner(ToStringAssigner.INSTANCE),
                    Assigner.Typing.STATIC))
  .make()

创建自定义参数绑定器

1
2
3
4
@Retention(RetentionPolicy.RUNTIME)
@interface StringValue {
  String value();
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
enum StringValueBinder
    implements TargetMethodAnnotationDrivenBinder.ParameterBinder<StringValue> {

  INSTANCE; // singleton

  @Override
  public Class<StringValue> getHandledType() {
    return StringValue.class;
  }

  @Override
  public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loaded<StringValue> annotation,
                                                         MethodDescription source,
                                                         ParameterDescription target,
                                                         Implementation.Target implementationTarget,
                                                         Assigner assigner,
                                                         Assigner.Typing typing) {
    if (!target.getType().asErasure().represents(String.class)) {
      throw new IllegalStateException(target + " makes illegal use of @StringValue");
    }
    StackManipulation constant = new TextConstant(annotation.loadSilent().value());
    return new MethodDelegationBinder.ParameterBinding.Anonymous(constant);
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class ToStringInterceptor {
  public static String makeString(@StringValue("Hello!") String value) {
    return value;
  }
}

new ByteBuddy()
  .subclass(Object.class)
  .method(named("toString"))
    .intercept(MethodDelegation.withDefaultConfiguration()
      .withBinders(StringValueBinder.INSTANCE)
      .to(ToStringInterceptor.class))
  .make()