diff --git a/core-java/src/main/java/com/baeldung/dynamicproxy/DynamicInvocationHandler.java b/core-java/src/main/java/com/baeldung/dynamicproxy/DynamicInvocationHandler.java new file mode 100644 index 0000000000..8bde2f703f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/dynamicproxy/DynamicInvocationHandler.java @@ -0,0 +1,19 @@ +package com.baeldung.dynamicproxy; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +public class DynamicInvocationHandler implements InvocationHandler { + + private static Logger LOGGER = LoggerFactory.getLogger(DynamicInvocationHandler.class); + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + LOGGER.info("Invoked method: {}", method.getName()); + + return 42; + } +} diff --git a/core-java/src/main/java/com/baeldung/dynamicproxy/TimingDynamicInvocationHandler.java b/core-java/src/main/java/com/baeldung/dynamicproxy/TimingDynamicInvocationHandler.java new file mode 100644 index 0000000000..942efc50cc --- /dev/null +++ b/core-java/src/main/java/com/baeldung/dynamicproxy/TimingDynamicInvocationHandler.java @@ -0,0 +1,36 @@ +package com.baeldung.dynamicproxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TimingDynamicInvocationHandler implements InvocationHandler { + + private static Logger LOGGER = LoggerFactory.getLogger(TimingDynamicInvocationHandler.class); + private final Map methods = new HashMap<>(); + + private Object target; + + public TimingDynamicInvocationHandler(Object target) { + this.target = target; + + for(Method method: target.getClass().getDeclaredMethods()) { + this.methods.put(method.getName(), method); + } + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + long start = System.nanoTime(); + Object result = methods.get(method.getName()).invoke(target, args); + long elapsed = System.nanoTime() - start; + + LOGGER.info("Executing {} finished in {} ns", method.getName(), elapsed); + + return result; + } +} diff --git a/core-java/src/test/java/com/baeldung/dynamicproxy/DynamicProxyTest.java b/core-java/src/test/java/com/baeldung/dynamicproxy/DynamicProxyTest.java new file mode 100644 index 0000000000..4386b11797 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/dynamicproxy/DynamicProxyTest.java @@ -0,0 +1,57 @@ +package com.baeldung.dynamicproxy; + +import org.junit.Test; + +import java.lang.reflect.Proxy; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.testng.Assert.fail; + +public class DynamicProxyTest { + + @Test + public void givenDynamicProxy_thenPutWorks() { + Map proxyInstance = (Map) Proxy.newProxyInstance(DynamicProxyTest.class.getClassLoader(), new Class[] { Map.class }, new DynamicInvocationHandler()); + + proxyInstance.put("hello", "world"); + } + + @Test + public void givenInlineDynamicProxy_thenGetWorksOtherMethodsDoNot() { + Map proxyInstance = (Map) Proxy.newProxyInstance(DynamicProxyTest.class.getClassLoader(), new Class[] { Map.class }, (proxy, method, methodArgs) -> { + + if (method.getName().equals("get")) { + return 42; + } else { + throw new UnsupportedOperationException("Unsupported method: " + method.getName()); + } + }); + + int result = (int) proxyInstance.get("hello"); + + assertEquals(42, result); + + try { + proxyInstance.put("hello", "world"); + fail(); + } catch(UnsupportedOperationException e) { + // expected + } + } + + @Test + public void givenTimingDynamicProxy_thenMethodInvokationsProduceTiming() { + Map mapProxyInstance = (Map) Proxy.newProxyInstance(DynamicProxyTest.class.getClassLoader(), new Class[] { Map.class }, new TimingDynamicInvocationHandler(new HashMap<>())); + + mapProxyInstance.put("hello", "world"); + assertEquals("world", mapProxyInstance.get("hello")); + + CharSequence csProxyInstance = (CharSequence) Proxy.newProxyInstance(DynamicProxyTest.class.getClassLoader(), new Class[] { CharSequence.class }, new TimingDynamicInvocationHandler("Hello World")); + + assertEquals('l', csProxyInstance.charAt(2)); + assertEquals(11, csProxyInstance.length()); + } + +}