How can I create proxy objects for SAM/functional interfaces using LambdaMetaFactory
ie. equivalent of
public static Object java.lang.reflect.Proxy.newProxyInstance(ClassLoader, Class<?>[], InvocationHandler)
Eg. I have multiple factory interfaces
interface X{
// members
// methods
}
interface Y{
// members
// methods
}
public interface Factory1{
X get(String name);
}
public interface Factory2{
Y get(String name);
}
.
.
.
public interface FactoryN{
someclassOrInterface get(String name);
}
and I want to generate the factory proxies at runtime tied to some prebuilt bean container e.g.
public Object getFactoryBean(String name){
return beanContainer.get(name);
}
something similar to
org.springframework.beans.factory.config.ServiceLocatorFactoryBean
but built on LambdaMetaFactory. I tried following code but gets an exception
static <T> T getFactory(Class<T> factoryClass) {
T factory =null;
try {
final MethodHandles.Lookup lookup = MethodHandles.lookup();
Class<?> beanType = factoryClass.getMethod("get", String.class).getReturnType();
final CallSite site = LambdaMetafactory.metafactory(lookup,
"get",
MethodType.methodType(factoryClass, String.class),
MethodType.methodType(beanType),
lookup.findStatic(ReflectionUtil.class, "getFactoryBean", MethodType.methodType(Object.class, String.class)),
MethodType.methodType(beanType));
factory = (T) site.getTarget().invoke();
} catch(Throwable e) {
e.printStackTrace();
}
return factory;
}
public static Object getFactoryBean(String beanName) {
return beanMap.get(beanName);
}
java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle(String)Factory1 to ()Object
at java.lang.invoke.MethodHandle.asTypeUncached(MethodHandle.java:775)
at java.lang.invoke.MethodHandle.asType(MethodHandle.java:761)
at java.lang.invoke.Invokers.checkGenericType(Invokers.java:321)
Thanks in advance.
Your code specifies a
String
argument for theinvokedType
argument instead of thesamMethodType
andinstantiatedMethodType
arguments. This would be the right thing if you want to capture aString
value and implement a functional signature without arguments.But you consistently show interfaces with a
String
argument and callinvoke()
without arguments. Therefore, the code should look likewhich can be simplified to