38 lines
1.3 KiB
Java
38 lines
1.3 KiB
Java
package tc.oc.commons.core.util;
|
|
|
|
import java.lang.invoke.MethodHandle;
|
|
import java.lang.reflect.Method;
|
|
import java.util.concurrent.ExecutionException;
|
|
import java.util.function.Function;
|
|
|
|
import com.google.common.base.Throwables;
|
|
import com.google.common.cache.Cache;
|
|
|
|
/**
|
|
* Forwards all method calls to the object returned from {@link #targetFor(Method)},
|
|
* through cached {@link MethodHandle}s. The handles are bound to the target
|
|
* object at creation time, so the return value of {@link #targetFor(Method)} must
|
|
* remain constant for any given {@link Method}.
|
|
*/
|
|
public abstract class CachingMethodHandleInvoker extends MethodHandleInvoker {
|
|
|
|
private final Cache<Method, MethodHandle> cache = CacheUtils.newBuilder().build();
|
|
|
|
@Override
|
|
protected MethodHandle boundMethodHandle(Method method) {
|
|
try {
|
|
return cache.get(method, () -> super.boundMethodHandle(method));
|
|
} catch(ExecutionException e) {
|
|
throw Throwables.propagate(e);
|
|
}
|
|
}
|
|
|
|
public static CachingMethodHandleInvoker caching(Function<? super Method, Object> targeter) {
|
|
return new CachingMethodHandleInvoker() {
|
|
@Override protected Object targetFor(Method method) {
|
|
return targeter.apply(method);
|
|
}
|
|
};
|
|
}
|
|
}
|