如何使用 byte buddy 在运行时有效地将接口与 POJO 相关联?
How to efficiently relate interface to POJO at runtime using byte buddy?
我有一个服务可以在几秒钟内创建和处理数千个 POJO,所以我的问题是:最有效的方法是什么?
下面是我当前的实现。能不能快点?
工厂:
public class ModelProxyFactory {
public static <T> T factory(Object entityProxy, Class<T> destinationType) throws IllegalAccessException, InstantiationException {
Class<?> proxyType = new ByteBuddy()
.subclass(destinationType)
.implement(ModelProxy.class)
.method(ElementMatchers.any())
.intercept(InvocationHandlerAdapter.of(new ModelInvocationHandler(entityProxy)))
.make().load(destinationType.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
T proxy = (T) proxyType.newInstance();
return proxy;
}
}
我需要我的 POJO 实现的接口:
public interface ModelProxy {
Object getEntityProxy();
}
我的调用处理程序:
public class ModelInvocationHandler implements InvocationHandler {
private Object entityProxy;
public ModelInvocationHandler(Object entityProxy) {
this.entityProxy = entityProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (ModelProxy.class.isAssignableFrom(method.getDeclaringClass())) {
if (method.getName().equals("getEntityProxy")) {
return entityProxy;
}
}
throw new RuntimeException("This object was not loaded from the database.");
}
}
对于那些想知道的人...是的,我正在尝试在 POJO 中复制休眠 LazyInitializationException 行为,并通过接口 [=28] 在我的 POJO 中保留延迟加载实体的引用=].
是的,您应该使用 TypeCache
并重复使用单个代理 class。不要注入特定的 InvocationHandler,而是使用 defineField
使其可用并更改检测以委托给该字段。然后,您可以实现一个额外的接口,该接口定义了一个 setter,您可以使用它来设置此字段。
我有一个服务可以在几秒钟内创建和处理数千个 POJO,所以我的问题是:最有效的方法是什么?
下面是我当前的实现。能不能快点?
工厂:
public class ModelProxyFactory {
public static <T> T factory(Object entityProxy, Class<T> destinationType) throws IllegalAccessException, InstantiationException {
Class<?> proxyType = new ByteBuddy()
.subclass(destinationType)
.implement(ModelProxy.class)
.method(ElementMatchers.any())
.intercept(InvocationHandlerAdapter.of(new ModelInvocationHandler(entityProxy)))
.make().load(destinationType.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
T proxy = (T) proxyType.newInstance();
return proxy;
}
}
我需要我的 POJO 实现的接口:
public interface ModelProxy {
Object getEntityProxy();
}
我的调用处理程序:
public class ModelInvocationHandler implements InvocationHandler {
private Object entityProxy;
public ModelInvocationHandler(Object entityProxy) {
this.entityProxy = entityProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (ModelProxy.class.isAssignableFrom(method.getDeclaringClass())) {
if (method.getName().equals("getEntityProxy")) {
return entityProxy;
}
}
throw new RuntimeException("This object was not loaded from the database.");
}
}
对于那些想知道的人...是的,我正在尝试在 POJO 中复制休眠 LazyInitializationException 行为,并通过接口 [=28] 在我的 POJO 中保留延迟加载实体的引用=].
是的,您应该使用 TypeCache
并重复使用单个代理 class。不要注入特定的 InvocationHandler,而是使用 defineField
使其可用并更改检测以委托给该字段。然后,您可以实现一个额外的接口,该接口定义了一个 setter,您可以使用它来设置此字段。