0Pricing
Java Academy · Lektion

Dynamische Proxies mit InvocationHandler

Erstellen Sie dynamische JDK-Proxies, um Aufrufe von Schnittstellenmethoden für Logging, Caching und Wiederholungen abzufangen.

Dynamische Proxies mit InvocationHandler ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Was ist ein Dynamic Proxy?

Ein JDK Dynamic Proxy ist ein zur Laufzeit erstelltes Objekt, das ein oder mehrere Interfaces implementiert. Alle Methodenaufrufe werden an einen von Ihnen bereitgestellten InvocationHandler weitergeleitet.

Einen Proxy mit Proxy.newProxyInstance erstellen

Rufen Sie Proxy.newProxyInstance(classLoader, interfaces[], handler) auf, um einen Proxy zu erstellen. Der Proxy implementiert alle aufgeführten Interfaces.

UserService proxy = (UserService) Proxy.newProxyInstance(
    UserService.class.getClassLoader(),
    new Class[]{UserService.class},
    new LoggingHandler(realService)
);
proxy.findById(42L); // intercepted by LoggingHandler

Das InvocationHandler-Interface

Implementieren Sie InvocationHandler, um jeden Methodenaufruf zu behandeln. Der Handler erhält das Proxy-Objekt, die aufgerufene Methode und die Argumente.

public class LoggingHandler implements InvocationHandler {
    private final Object target;
    public LoggingHandler(Object target) { this.target = target; }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(">> " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("<< " + method.getName());
        return result;
    }
}

Proxy für Caching

Ein InvocationHandler kann Ergebnisse cachen: Wenn der Cache ein Ergebnis für die Argumente enthält, geben Sie es zurück. Andernfalls rufen Sie die echte Methode auf und speichern das Ergebnis.

public class CachingHandler implements InvocationHandler {
    private final Object target;
    private final Map<String, Object> cache = new HashMap<>();
    public CachingHandler(Object target) { this.target = target; }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String key = method.getName() + Arrays.toString(args);
        return cache.computeIfAbsent(key, k -> {
            try { return method.invoke(target, args); }
            catch (Exception e) { throw new RuntimeException(e); }
        });
    }
}

Proxy für Wiederholungslogik

Umschließen Sie Methodenaufrufe mit einer Wiederholungsschleife. Tritt eine Exception auf, wiederholen Sie den Aufruf bis zu N-mal, bevor Sie die Exception erneut auslösen.

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    for (int attempt = 1; attempt <= 3; attempt++) {
        try { return method.invoke(target, args); }
        catch (InvocationTargetException e) {
            if (attempt == 3) throw e.getCause();
            Thread.sleep(1000L * attempt);
        }
    }
    throw new RuntimeException("unreachable");
}

Proxy für Transaktionsverwaltung

Springs @Transactional verwendet einen Dynamic Proxy, um vor einem Methodenaufruf eine Transaktion zu starten und sie danach zu bestätigen oder zurückzurollen – ohne dass der Aufrufer davon etwas bemerkt.

Prüfen, ob ein Objekt ein Proxy ist

Verwenden Sie Proxy.isProxyClass(obj.getClass()), um Proxys zu erkennen, und Proxy.getInvocationHandler(proxy), um den Handler abzurufen.

if (Proxy.isProxyClass(service.getClass())) {
    InvocationHandler h = Proxy.getInvocationHandler(service);
    System.out.println("Handler: " + h.getClass().getSimpleName());
}

Einschränkungen von JDK Dynamic Proxies

JDK Dynamic Proxies funktionieren nur mit Interfaces – konkrete Klassen können sie nicht als Proxy abbilden. Für klassenbasierte Proxys verwenden Sie CGLIB, das Spring intern auch für @Configuration-Klassen einsetzt.

CGLIB als Alternative

CGLIB erzeugt zur Laufzeit eine Unterklasse der Zielklasse und überschreibt alle nicht als final markierten Methoden. Spring verwendet CGLIB, wenn keine Interfaces vorhanden sind. Eine Anmerkung ist nicht erforderlich – die Verwendung bleibt transparent.

Proxys in Hibernate

Hibernate lädt Entity-Beziehungen mithilfe von CGLIB-/Byte-Buddy-Proxys verzögert. Wenn Sie auf eine Lazy Collection zugreifen, führt der Proxy eine SQL-Abfrage aus.

// Hibernate creates a proxy for:
@ManyToOne(fetch = FetchType.LAZY)
private Department department;
// Accessing dept triggers a DB query via the proxy

Leistung von Proxys

Der Methodenversand über einen Dynamic Proxy ist etwa 5- bis 10-mal langsamer als ein direkter Aufruf. Für sehr häufig durchlaufene Pfade sollten Sie stattdessen die Codegenerierung zur Compile-Zeit (APT) oder MethodHandles in Betracht ziehen.

Schnelltest

Was ist die wichtigste Einschränkung von JDK Dynamic Proxies?

Zusammenfassung

JDK Dynamic Proxies fangen über InvocationHandler Methodenaufrufe von Interfaces ab. Verwenden Sie sie für Logging, Caching, Wiederholungen und Transaktionsverwaltung. Für Proxys von Klassen verwenden Sie CGLIB. Cachen Sie die Proxy-Erstellung, da sie auf Reflection basiert und nicht kostenlos ist.

Häufig gestellte Fragen

Ist die Lektion „Dynamische Proxies mit InvocationHandler“ kostenlos?

Ja — der vollständige Text von „Dynamische Proxies mit InvocationHandler“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Dynamische Proxies mit InvocationHandler“?

Erstellen Sie dynamische JDK-Proxies, um Aufrufe von Schnittstellenmethoden für Logging, Caching und Wiederholungen abzufangen. Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Java Academy zu starten?

Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Dynamische Proxies mit InvocationHandler“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?

Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Klasseninspektion mit Reflection
  2. Methoden aufrufen und auf Felder zugreifen
  3. Dynamische Proxies mit InvocationHandler
  4. Reflection-Performance und Alternativen
← Zurück zu Java Academy