Welke soorten proxy-servers kent u?
sobes.tech AI
Antwoord van AI
In Java, er zijn de volgende soorten proxies:
-
Statische (Static Proxy): Wordt geïmplementeerd door het maken van een aparte wrapper-klasse die een verwijzing bevat naar het echte object en methoden aanroept, terwijl hij zijn eigen logica toevoegt (bijvoorbeeld logging, authenticatie).
// Interface interface Service { void doSomething(); } // Echte object class RealService implements Service { @Override public void doSomething() { System.out.println("Echte actie"); } } // Statische proxy class StaticServiceProxy implements Service { private final Service realService; public StaticServiceProxy(Service realService) { this.realService = realService; } @Override public void doSomething() { System.out.println("Voor het aanroepen van de echte methode"); realService.doSomething(); System.out.println("Na het aanroepen van de echte methode"); } } -
Dynamische (Dynamic Proxy): Wordt tijdens runtime gemaakt met behulp van Reflection API en vereist dat het geproxyde object ten minste één interface implementeert. Hiermee kunnen proxies voor meerdere klassen die één interface implementeren worden gegenereerd zonder voor elke klasse een aparte proxy te maken.
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // Handler voor dynamische proxies class DynamicServiceInvocationHandler implements InvocationHandler { private final Object target; // Doelobject public DynamicServiceInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Voor het aanroepen van methode " + method.getName()); Object result = method.invoke(target, args); // Aanroepen van de methode op het doelobject System.out.println("Na het aanroepen van methode " + method.getName()); return result; } } // Voorbeeld van gebruik (voor de interface Service uit het statische proxy-voorbeeld) // Service realService = new RealService(); // Service proxy = (Service) Proxy.newProxyInstance( // realService.getClass().getClassLoader(), // realService.getClass().getInterfaces(), // new DynamicServiceInvocationHandler(realService)); // proxy.doSomething(); -
CGLIB Proxy: Gebaseerd op bytecode-generatie en vereist geen interface-implementatie. Kan specifieke klassen proxyen (als ze niet final zijn en methoden niet final). Het is in sommige scenario's efficiënter dan standaard dynamische proxies.
// Voorbeeld van CGLIB gebruik (vereist externe bibliotheek) // public class RealService { // public void doSomething() { // System.out.println("Echte actie"); // } // } // 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("Voor het aanroepen van methode " + method.getName()); // Object result = proxy.invokeSuper(obj, args); // Aanroepen van de superklasse methode // System.out.println("Na het aanroepen van methode " + method.getName()); // return result; // } // } // // Gebruik voorbeeld: // // Enhancer enhancer = new Enhancer(); // // enhancer.setSuperclass(RealService.class); // // enhancer.setCallback(new CglibServiceInterceptor()); // // RealService proxy = (RealService) enhancer.create(); // // proxy.doSomething();
Belangrijkste verschillen:
| Proxytipo | Vereist Interface | Generatie | Flexibiliteit | Prestaties | Toepassing |
|---|---|---|---|---|---|
| Statisch | Ja | Handmatig | Laag (voor elke klasse) | Hoog | Eenvoudige gevallen, structuur bekend |
| Dynamisch | Ja | Tijdens runtime | Hoog (voor interfaces) | Gemiddeld | Algemene logica voor interfaces, AOP |
| CGLIB | Nee | Tijdens runtime | Hoog (voor klassen) | Hoog | AOP, proxying van klassen zonder interfaces |