Skip to content

Instantly share code, notes, and snippets.

@NagyGa1
Created March 13, 2017 03:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NagyGa1/ee1f2f0fb78821127f589b523d56ff29 to your computer and use it in GitHub Desktop.
Save NagyGa1/ee1f2f0fb78821127f589b523d56ff29 to your computer and use it in GitHub Desktop.
import com.cpox.model.partner.Partner;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.InvocationHandlerAdapter;
import net.bytebuddy.implementation.MethodDelegation;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import static net.bytebuddy.matcher.ElementMatchers.isClone;
import static net.bytebuddy.matcher.ElementMatchers.isEquals;
import static net.bytebuddy.matcher.ElementMatchers.isGetter;
import static net.bytebuddy.matcher.ElementMatchers.isHashCode;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
/**
* Simple proxying using Byte Buddy.
* <p>
* All methods of the Partner class are delegated to the original proxied object, except String getters that are
* handled by the Invocation Handler.
* <p>
* Decided not to use this in production because there are simpler ways to handle LOV internal to screen value
* using BeanUtils and cloning the Partner object, then replacing the defined String fields.
*/
public class TestInvocationHandler {
private static final Logger LOG = LoggerFactory.getLogger(TestInvocationHandler.class);
protected interface MyProxyInterface {
void setInvocationHandler(MyHandler handler);
Partner getProxied();
void setProxied(Partner partner);
}
protected static class MyHandler implements InvocationHandler {
@Override
public Object invoke(final Object o, final Method method, final Object[] objects) throws Throwable {
LOG.debug("Invoked: {}", method.getName());
return method.invoke(((MyProxyInterface) o).getProxied(), objects);
}
}
@Test
public void testApache() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
final Class<? extends Partner> a = new ByteBuddy()
.subclass(Partner.class)
.defineField("invocationHandler", MyHandler.class)
.defineField("proxied", Partner.class)
.implement(MyProxyInterface.class)
.intercept(FieldAccessor.ofBeanProperty())
// delegate String getters to invocationHandler
.method(isGetter(String.class))
.intercept(InvocationHandlerAdapter.toField("invocationHandler"))
// delegate everything else to the proxied instance
.method(not(
isGetter(String.class)
.or(named("setInvocationHandler"))
.or(named("setProxied"))
.or(named("getProxied"))
.or(isEquals())
.or(isHashCode())
.or(isClone())
))
.intercept(MethodDelegation.toField("proxied"))
.make()
.load(TestInvocationHandler.class.getClassLoader())
.getLoaded();
// for (int i = 0; i < 10; i++) {
final Partner partner = new Partner();
partner.setGender("My Gender");
partner.setDateOfBirth(new Date());
final Partner proxy = a.newInstance();
((MyProxyInterface) proxy).setInvocationHandler(new MyHandler());
((MyProxyInterface) proxy).setProxied(partner);
// a.getDeclaredField("invocationHandler").set(proxy, new MyHandler(p));
// a.getDeclaredField("partner").set(proxy, p);
System.out.println(" " + proxy.getGender());
System.out.println(" " + proxy.getDateOfBirth());
// }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment