gpt4 book ai didi

java - 如何使用 LambdaMetaFactory 在运行时创建代理对象?

转载 作者:行者123 更新时间:2023-12-01 14:21:07 31 4
gpt4 key购买 nike

如何使用 LambdaMetaFactory 为 SAM/功能接口(interface)创建代理对象

即。相当于 public static Object java.lang.reflect.Proxy.newProxyInstance(ClassLoader, Class<?>[], InvocationHandler)

例如。我有多个工厂接口(interface)

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);
}

我想在运行时生成绑定(bind)到一些预构建 bean 容器的工厂代理例如

public Object getFactoryBean(String name){ 
return beanContainer.get(name);
}

类似于

org.springframework.beans.factory.config.ServiceLocatorFactoryBean

但建立在 LambdaMetaFactory 之上。我尝试了以下代码但出现异常

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)

提前致谢。

最佳答案

您的代码为 invokedType 参数指定了一个 String 参数,而不是 samMethodTypeinstantiatedMethodType 参数。如果您想捕获 String 值并实现不带参数的功能签名,这将是正确的做法。

但是您始终显示带有 String 参数的接口(interface),并在没有参数的情况下调用 invoke()。因此,代码应该是这样的

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),
MethodType.methodType(beanType, String.class),
lookup.findStatic(ReflectionUtil.class, "getFactoryBean",
MethodType.methodType(Object.class, String.class)),
MethodType.methodType(beanType, String.class));
factory = (T)site.getTarget().invoke();
} catch(Throwable e) {
e.printStackTrace();
}
return factory;
}

可以简化为

static <T> T getFactory(Class<T> factoryClass) {
try {
MethodHandles.Lookup lookup = MethodHandles.lookup();
Class<?> beanType = factoryClass.getMethod("get", String.class).getReturnType();
MethodHandle target = lookup.findStatic(ReflectionUtil.class, "getFactoryBean",
MethodType.methodType(Object.class, String.class));
MethodType funcType = target.type().changeReturnType(beanType);
return (T)LambdaMetafactory.metafactory(
lookup, "get", MethodType.methodType(factoryClass), funcType, target, funcType)
.getTarget().invoke();
} catch(Throwable e) {
e.printStackTrace();
return null; // rethink this error handling
}
}

关于java - 如何使用 LambdaMetaFactory 在运行时创建代理对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60253943/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com