Welche Arten von Proxy-Servern kennen Sie?
sobes.tech KI
Antwort von AI
In Java gibt es die folgenden Arten von Proxies:
-
Statischer Proxy: Wird durch Erstellen einer separaten Wrapper-Klasse implementiert, die eine Referenz auf das echte Objekt enthält und Aufrufe an dieses delegiert, wobei sie eigene Logik hinzufügt (z.B. Logging, Autorisierung).
// Schnittstelle interface Service { void doSomething(); } // Echtes Objekt class RealService implements Service { @Override public void doSomething() { System.out.println("Echte Aktion"); } } // Statischer Proxy class StaticServiceProxy implements Service { private final Service realService; public StaticServiceProxy(Service realService) { this.realService = realService; } @Override public void doSomething() { System.out.println("Vor dem Aufruf der echten Methode"); realService.doSomething(); System.out.println("Nach dem Aufruf der echten Methode"); } } -
Dynamischer Proxy: Wird zur Laufzeit mit Reflection API erstellt und erfordert, dass das proxy-Objekt mindestens eine Schnittstelle implementiert. Ermöglicht die Generierung von Proxies für mehrere Klassen, die eine Schnittstelle implementieren, ohne für jede Klasse eine separate Klasse zu erstellen.
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // Handler für dynamische Proxies class DynamicServiceInvocationHandler implements InvocationHandler { private final Object target; // Zielobjekt public DynamicServiceInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Vor dem Methodenaufruf " + method.getName()); Object result = method.invoke(target, args); // Aufruf der Zielmethode System.out.println("Nach dem Methodenaufruf " + method.getName()); return result; } } // Beispielnutzung (für die Service-Schnittstelle des statischen Proxies) // Service realService = new RealService(); // Service proxy = (Service) Proxy.newProxyInstance( // realService.getClass().getClassLoader(), // realService.getClass().getInterfaces(), // new DynamicServiceInvocationHandler(realService)); // proxy.doSomething(); -
CGLIB Proxy: Basierend auf Bytecode-Generation und erfordert keine Schnittstelle. Kann konkrete Klassen proxyen (sofern sie nicht final sind und ihre Methoden nicht final sind). Ist in bestimmten Szenarien leistungsfähiger als der Standard-Dynamic Proxy.
// Beispiel für CGLIB (benötigt externe Bibliothek) // public class RealService { // public void doSomething() { // System.out.println("Echte Aktion"); // } // } // import net.sf.cglib.proxy.MethodInterceptor; // import net.sf.cglib.proxy.MethodProxy; // import net.sf.cglib.proxy.Enhancer; // class CglibServiceInterceptor implements MethodInterceptor { // @Override // public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { // System.out.println("Vor dem Methodenaufruf " + method.getName()); // Object result = proxy.invokeSuper(obj, args); // Aufruf der Superklasse (Originalobjekt) // System.out.println("Nach dem Methodenaufruf " + method.getName()); // return result; // } // } // // Beispielnutzung: // // Enhancer enhancer = new Enhancer(); // // enhancer.setSuperclass(RealService.class); // // enhancer.setCallback(new CglibServiceInterceptor()); // // RealService proxy = (RealService) enhancer.create(); // // proxy.doSomething();
Hauptunterschiede:
| Proxy-Typ | Benötigt Schnittstelle | Generierung | Flexibilität | Leistung | Anwendung |
|---|---|---|---|---|---|
| Statisch | Ja | Manuell | Niedrig (für jede Klasse) | Hoch | Einfache Fälle, bekannte Struktur |
| Dynamisch | Ja | Zur Laufzeit | Hoch (für Schnittstellen) | Mittel | Gemeinsame Logik für Schnittstellen, AOP |
| CGLIB | Nein | Zur Laufzeit | Hoch (für Klassen) | Hoch | AOP, Proxy von Klassen ohne Schnittstellen |