友情支持

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

支付宝

微信

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

wx jikerizhi

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

属性和方法

1
2
3
4
5
6
7
8
String toString = new ByteBuddy()
  .subclass(Object.class)
  .name("example.Type")
  .make()
  .load(getClass().getClassLoader())
  .getLoaded()
  .newInstance() // Java reflection API
  .toString();
1
2
3
4
5
6
7
8
9
String toString = new ByteBuddy()
  .subclass(Object.class)
  .name("example.Type")
  .method(named("toString")).intercept(FixedValue.value("Hello World!"))
  .make()
  .load(getClass().getClassLoader())
  .getLoaded()
  .newInstance()
  .toString();
1
named("toString").and(returns(String.class)).and(takesArguments(0))
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Foo {
  public String bar() { return null; }
  public String foo() { return null; }
  public String foo(Object o) { return null; }
}

Foo dynamicFoo = new ByteBuddy()
  .subclass(Foo.class)
  .method(isDeclaredBy(Foo.class)).intercept(FixedValue.value("One!"))
  .method(named("foo")).intercept(FixedValue.value("Two!"))
  .method(named("foo").and(takesArguments(1))).intercept(FixedValue.value("Three!"))
  .make()
  .load(getClass().getClassLoader())
  .getLoaded()
  .newInstance();

深入细看一个固定值

1
2
3
4
new ByteBuddy()
  .subclass(Foo.class)
  .method(isDeclaredBy(Foo.class)).intercept(FixedValue.value(0))
  .make();

委托方法调用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Source {
  public String hello(String name) { return null; }
}

class Target {
  public static String hello(String name) {
    return "Hello " + name + "!";
  }
}

String helloWorld = new ByteBuddy()
  .subclass(Source.class)
  .method(named("hello")).intercept(MethodDelegation.to(Target.class))
  .make()
  .load(getClass().getClassLoader())
  .getLoaded()
  .newInstance()
  .hello("World");
1
2
3
4
5
class Target {
  public static String intercept(String name) { return "Hello " + name + "!"; }
  public static String intercept(int i) { return Integer.toString(i); }
  public static String intercept(Object o) { return o.toString(); }
}
1
void foo(Object o1, Object o2)
1
void foo(@Argument(0) Object o1, @Argument(1) Object o2)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class MemoryDatabase {
  public List<String> load(String info) {
    return Arrays.asList(info + ": foo", info + ": bar");
  }
}

class LoggerInterceptor {
  public static List<String> log(@SuperCall Callable<List<String>> zuper)
      throws Exception {
    System.out.println("Calling database");
    try {
      return zuper.call();
    } finally {
      System.out.println("Returned from database");
    }
  }
}

MemoryDatabase loggingDatabase = new ByteBuddy()
  .subclass(MemoryDatabase.class)
  .method(named("load")).intercept(MethodDelegation.to(LoggerInterceptor.class))
  .make()
  .load(getClass().getClassLoader())
  .getLoaded()
  .newInstance();
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class LoggingMemoryDatabase extends MemoryDatabase {

  private class LoadMethodSuperCall implements Callable {

    private final String info;
    private LoadMethodSuperCall(String info) {
      this.info = info;
    }

    @Override
    public Object call() throws Exception {
      return LoggingMemoryDatabase.super.load(info);
    }
  }

  @Override
  public List<String> load(String info) {
    return LoggerInterceptor.log(new LoadMethodSuperCall(info));
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class ChangingLoggerInterceptor {
  public static List<String> log(String info, @Super MemoryDatabase zuper) {
    System.out.println("Calling database");
    try {
      return zuper.load(info + " (logged access)");
    } finally {
      System.out.println("Returned from database");
    }
  }
}
1
2
3
4
class Loop {
  public String loop(String value) { return value; }
  public int loop(int value) { return value; }
}
1
2
3
4
5
6
7
class Interceptor {
  @RuntimeType
  public static Object intercept(@RuntimeType Object value) {
    System.out.println("Invoked method with: " + value);
    return value;
  }
}
1
2
3
interface Forwarder<T, S> {
  T to(S target);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class ForwardingLoggerInterceptor {

  private final MemoryDatabase memoryDatabase; // constructor omitted

  public List<String> log(@Pipe Forwarder<List<String>, MemoryDatabase> pipe) {
    System.out.println("Calling database");
    try {
      return pipe.to(memoryDatabase);
    } finally {
      System.out.println("Returned from database");
    }
  }
}

MemoryDatabase loggingDatabase = new ByteBuddy()
  .subclass(MemoryDatabase.class)
  .method(named("load")).intercept(MethodDelegation.withDefaultConfiguration()
    .withBinders(Pipe.Binder.install(Forwarder.class)))
    .to(new ForwardingLoggerInterceptor(new MemoryDatabase()))
  .make()
  .load(getClass().getClassLoader())
  .getLoaded()
  .newInstance();

调用超类方法

1
2
3
new ByteBuddy()
  .subclass(Object.class)
  .make()
1
2
3
new ByteBuddy()
  .subclass(Object.class, ConstructorStrategy.Default.IMITATE_SUPER_TYPE)
  .make()

调用默认方法

1
2
3
4
5
6
7
interface First {
  default String qux() { return "FOO"; }
}

interface Second {
  default String qux() { return "BAR"; }
}
1
2
3
4
5
6
new ByteBuddy(ClassFileVersion.JAVA_V8)
  .subclass(Object.class)
  .implement(First.class)
  .implement(Second.class)
  .method(named("qux")).intercept(DefaultMethodCall.prioritize(First.class))
  .make()

调用特定方法

1
2
3
4
5
public class SampleClass {
  public SampleClass(int unusedValue) {
    super();
  }
}
1
2
3
4
5
new ByteBuddy()
  .subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
  .defineConstructor(Arrays.<Class<?>>asList(int.class), Visibility.PUBLIC)
  .intercept(MethodCall.invoke(Object.class.getDeclaredConstructor()))
  .make()

访问属性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class UserType {
  public String doSomething() { return null; }
}

interface Interceptor {
  String doSomethingElse();
}

interface InterceptionAccessor {
  Interceptor getInterceptor();
  void setInterceptor(Interceptor interceptor);
}

interface InstanceCreator {
  Object makeInstance();
}
1
2
3
4
5
6
7
8
9
Class<? extends UserType> dynamicUserType = new ByteBuddy()
  .subclass(UserType.class)
    .method(not(isDeclaredBy(Object.class)))
    .intercept(MethodDelegation.toField("interceptor"))
  .defineField("interceptor", Interceptor.class, Visibility.PRIVATE)
  .implement(InterceptionAccessor.class).intercept(FieldAccessor.ofBeanProperty())
  .make()
  .load(getClass().getClassLoader())
  .getLoaded();
1
2
3
4
5
6
7
InstanceCreator factory = new ByteBuddy()
  .subclass(InstanceCreator.class)
    .method(not(isDeclaredBy(Object.class)))
    .intercept(MethodDelegation.construct(dynamicUserType))
  .make()
  .load(dynamicUserType.getClassLoader())
  .getLoaded().newInstance();
1
2
3
4
5
6
7
8
9
class HelloWorldInterceptor implements Interceptor {
  @Override
  public String doSomethingElse() {
    return "Hello World!";
  }
}

UserType userType = (UserType) factory.makeInstance();
((InterceptionAccessor) userType).setInterceptor(new HelloWorldInterceptor());

杂项