Master Java Proxy: From Static to JDK Dynamic Proxy with Real Code

This article explains the proxy design pattern, shows how to implement static proxies in Java with concrete code examples, discusses their limitations, and then demonstrates JDK dynamic proxies using InvocationHandler and Proxy classes, including generated proxy class details.

Senior Brother's Insights
Senior Brother's Insights
Senior Brother's Insights
Master Java Proxy: From Static to JDK Dynamic Proxy with Real Code

Proxy Pattern Overview

The proxy pattern provides a surrogate object that controls access to a real subject, allowing additional behavior such as logging or access control without modifying the original class.

Roles in the Proxy Pattern

Subject : defines the common interface for both real and proxy objects.

RealSubject : the actual business logic implementation.

Proxy : holds a reference to a RealSubject and forwards calls, optionally adding extra processing.

Static Proxy Example

We define an interface Sell with methods sell() and ad(). Vendor implements this interface as the real subject, while Shop implements the same interface and delegates calls to a Vendor instance, allowing extra logic such as logging or permission checks.

/**
 * 委托类和代理类都实现了Sell接口
 */
public interface Sell {
    void sell();
    void ad();
}

/**
 * 供应商(真实主题)
 */
public class Vendor implements Sell {
    @Override
    public void sell() {
        System.out.println("Shop sell goods");
    }
    @Override
    public void ad() {
        System.out.println("Shop advert goods");
    }
}

/**
 * 超市(代理)
 */
public class Shop implements Sell {
    private Sell sell;
    public Shop(Sell sell) { this.sell = sell; }
    @Override
    public void sell() {
        System.out.println("代理类Shop,处理sell");
        sell.sell();
    }
    @Override
    public void ad() {
        System.out.println("代理类Shop,处理ad");
        sell.ad();
    }
}

/**
 * 静态代理测试
 */
public class StaticProxy {
    public static void main(String[] args) {
        Vendor vendor = new Vendor();
        Sell sell = new Shop(vendor);
        sell.ad();
        sell.sell();
    }
}

Drawbacks of Static Proxy

When many classes need proxies, each requires a separate proxy class or a huge monolithic proxy, leading to code bloat.

Any change to the interface forces updates in both the real and proxy classes, making maintenance difficult.

Dynamic Proxy Introduction

Dynamic proxies are created at runtime, eliminating the need for hand‑written proxy classes. The JDK provides java.lang.reflect.Proxy and java.lang.reflect.InvocationHandler to generate proxy instances that implement specified interfaces.

JDK Dynamic Proxy Implementation

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Date;

public class LogHandler implements InvocationHandler {
    private Object target;
    public LogHandler(Object target) { this.target = target; }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object result = method.invoke(target, args);
        after();
        return result;
    }
    private void before() {
        System.out.println(String.format("log start time [%s] ", new Date()));
    }
    private void after() {
        System.out.println(String.format("log end time [%s] ", new Date()));
    }
}

import java.lang.reflect.Proxy;

/**
 * 动态代理测试
 */
public class DynamicProxyMain {
    public static void main(String[] args) {
        LogHandler logHandler = new LogHandler(new Vendor());
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        Sell sell = (Sell) Proxy.newProxyInstance(
            Sell.class.getClassLoader(),
            new Class[]{Sell.class},
            logHandler);
        sell.sell();
        sell.ad();
    }
}

Running the program prints log messages before and after each method invocation, demonstrating how cross‑cutting concerns can be added without touching the original Vendor code.

Generated Proxy Class Details

When the system property sun.misc.ProxyGenerator.saveGeneratedFiles is set, the JDK writes the generated proxy class (e.g., $Proxy0.class) to disk. Decompiling it reveals a final class that extends Proxy and implements the target interface, with method dispatch delegated to the InvocationHandler.

package com.sun.proxy;
import com.choupangxia.proxy.Sell;
import java.lang.reflect.*;
public final class $Proxy0 extends Proxy implements Sell {
    private static Method m1; // equals
    private static Method m2; // toString
    private static Method m3; // sell
    private static Method m4; // ad
    private static Method m0; // hashCode
    public $Proxy0(InvocationHandler h) { super(h); }
    public final void sell() { super.h.invoke(this, m3, null); }
    public final void ad() { super.h.invoke(this, m4, null); }
    // other Object methods omitted for brevity
    static {
        try {
            m1 = Object.class.getMethod("equals", Object.class);
            m2 = Object.class.getMethod("toString");
            m3 = Sell.class.getMethod("sell");
            m4 = Sell.class.getMethod("ad");
            m0 = Object.class.getMethod("hashCode");
        } catch (Exception e) { throw new RuntimeException(e); }
    }
}

Conclusion

The proxy pattern, especially when combined with JDK dynamic proxies, enables clean separation of cross‑cutting concerns such as logging, security, or transaction management. Understanding static and dynamic proxies lays a solid foundation for using higher‑level frameworks that rely on these mechanisms.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsJavaJDKDynamic ProxyProxy PatternStatic Proxy
Senior Brother's Insights
Written by

Senior Brother's Insights

A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.