-
Notifications
You must be signed in to change notification settings - Fork 0
/
Example2.java
executable file
·67 lines (57 loc) · 2.26 KB
/
Example2.java
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package com.github.forax.virtualbean.example;
import com.github.forax.virtualbean.BeanFactory;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Objects;
import static com.github.forax.virtualbean.BeanFactory.Interceptor.Kind.POST;
/**
* Implement an annotation ParametersNonNull that checks if the parameters are null
* Same behavior as Example.java but uses an interceptor instead of an advice
* which is a little more complex to use but more efficient.
*/
public class Example2 {
@Retention(RetentionPolicy.RUNTIME)
@interface ParametersNonNull { }
private static final MethodHandle REQUIRE_NON_NULL;
static {
try {
REQUIRE_NON_NULL = MethodHandles.lookup().findStatic(Objects.class, "requireNonNull", MethodType.methodType(Object.class, Object.class, String.class));
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new AssertionError(e);
}
}
public static void main(String[] args) {
var lookup = MethodHandles.lookup();
var beanFactory = new BeanFactory(lookup);
beanFactory.registerInterceptor(ParametersNonNull.class, (kind, method, type) -> {
if (kind == POST) {
return null;
}
var parameterTypes = method.getParameterTypes();
var filters = new MethodHandle[parameterTypes.length];
for(var i = 0; i < parameterTypes.length; i++) {
var parameterType = parameterTypes[i];
if (parameterType.isPrimitive()) {
continue;
}
var requireNonNull = MethodHandles.insertArguments(REQUIRE_NON_NULL, 1, "argument " + i + " of " + method + " is null");
var filter = requireNonNull.asType(MethodType.methodType(parameterType, parameterType));
filters[i] = filter;
}
var empty = MethodHandles.empty(type);
return MethodHandles.filterArguments(empty, 1, filters);
});
interface HelloManager {
@ParametersNonNull
default void sayHello(String text) {
System.out.println("hello " + text);
}
}
var helloManager = beanFactory.create(HelloManager.class);
helloManager.sayHello("Bob");
helloManager.sayHello(null);
}
}