友情支持
如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜
有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。
公众号的微信号是: 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());