项目作者: forax

项目描述 :
A simple API that shows how,to use Hidden class to create proxies
高级语言: Java
项目地址: git://github.com/forax/hidden_proxy.git
创建时间: 2020-04-08T12:30:55Z
项目社区:https://github.com/forax/hidden_proxy

开源协议:MIT License

下载


hidden_proxy

A simple API that shows how,to use Hidden class to create proxies.

This is a replacement of java.lang.reflect.Proxy API of Java using a more modern design leading to must faster proxies implementation. See the javadoc of Proxy for more information.

This code is using the Hidden Class API JEP 371 that was introduced in java 15,
so it requires Java 16 to run.

Example

Let say we have an interface HelloProxy with an abstract method hello and a static method implementation somewhere else

  1. interface HelloProxy {
  2. String hello(String text);
  3. }
  4. static class Impl {
  5. static String impl(int repeated, String text) {
  6. return text.repeat(repeated);
  7. }
  8. }

The method Proxy.defineProxy(lookup, interfaces, overriden, field, linker) let you dynamically create a class
that implements the interface HelloProxy with a field (here an int).
The return value of defineProxy is a lookup you can use to find the constructor and
invoke it invoke with the value of the field.
Then the first time an abstract method of the interface is called, here when calling proxy.hello("proxy"),
the linker is called to ask how the abstract method should be implemented.
Here the linker will use the method impl and discard (using dropArguments) the first argument (the proxy)
before calling the method impl.
So when calling the method hello, the method impl will be called with the field stored inside the proxy
as first argument followed by the arguments of the method `hello``.

  1. Lookup lookup = MethodHandles.lookup();
  2. MethodHandle impl = lookup.findStatic(Impl.class, "impl",
  3. methodType(String.class, int.class, String.class));
  4. Proxy.Linker linker = methodInfo -> switch(methodInfo.getName()) {
  5. case "hello" -> MethodHandles.dropArguments(impl, 0, HelloProxy.class);
  6. default -> fail("unknown method " + methodInfo);
  7. };
  8. Lookup proxyLookup = Proxy.defineProxy(lookup,
  9. new Class<?>[] { HelloProxy.class }, // proxy interfaces
  10. __ -> false, // don't override toString, equals and hashCode
  11. int.class, // proxy field
  12. linker);
  13. MethodHandle constructor = proxyLookup.findConstructor(proxyLookup.lookupClass(),
  14. methodType(void.class, int.class));
  15. HelloProxy proxy = (HelloProxy) constructor.invoke(2);
  16. assertEquals("proxyproxy", proxy.hello("proxy"));

If you want more examples, you can take a look to the test class ProxyTest.