I have a service that creates and processes thousands of POJOs in a few seconds so my question is: What's the most efficient way to do it?
Here's my current implementation below. Can it be faster?
The factory:
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;
}
}
Interface that I need my POJO to implement:
public interface ModelProxy {
Object getEntityProxy();
}
My Invocation Handler:
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.");
}
}
For those who are wondering... Yes, I'm trying to replicate the hibernate LazyInitializationException behavior in a POJO and keep the reference of the lazy loaded entity in my POJO via the interface 'ModelProxy'.
Yes, you should use a TypeCache
and reuse a single proxy class. Instead of injecting a specific InvocationHandler, use defineField
to make one available and change the instrumentation to delegate to this field. You can then implement an additional interface that defines a setter which you use to set this field.