Phase 20 of 20 · Topic 20.4

Java Reflection API & Dynamic Proxies

1Concept

The Reflection API (`java.lang.reflect`) allows inspecting classes, fields, and methods at runtime, and invoking private methods. Dynamic Proxies (`Proxy.newProxyInstance`) generate runtime implementations of interfaces using an `InvocationHandler`, powering Spring AOP and Hibernate proxies.

2Architecture Diagram

Client Call ---> [ Dynamic Proxy ] ---> [ InvocationHandler.invoke() ] ---> Target Method
                                                    |
                                            Adds Logging / Security / Metrics

3Code Example

Core Java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxyDemo {
    interface GreetingService {
        void greet(String name);
    }

    static class GreetingServiceImpl implements GreetingService {
        public void greet(String name) { System.out.println("Hello, " + name); }
    }

    public static void main(String[] args) {
        GreetingService target = new GreetingServiceImpl();

        // Dynamic Proxy interceptor
        GreetingService proxy = (GreetingService) Proxy.newProxyInstance(
            GreetingService.class.getClassLoader(),
            new Class<?>[]{GreetingService.class},
            (p, method, args1) -> {
                System.out.println("[AOP Before] Intercepting: " + method.getName());
                Object result = method.invoke(target, args1);
                System.out.println("[AOP After] Completed call.");
                return result;
            }
        );

        proxy.greet("Senior Engineer");
    }
}

4Expected Output

[AOP Before] Intercepting: greet
Hello, Senior Engineer
[AOP After] Completed call.

5Key Takeaways

  • Dynamic proxies require interfaces; for class-based proxies, bytecode tools like ByteBuddy or CGLIB are required.
  • Reflection bypasses compile-time type safety and carries a minor performance cost.
  • In JPMS, private reflection requires packages to be explicitly `opened` in module-info.