Aké typy proxy serverov poznáte?
sobes.tech AI
Odpoveď od AI
V Jave existujú nasledujúce typy proxy:
-
Statický (Static Proxy): Implementuje sa vytvorením samostatnej triedy-obalu, ktorá obsahuje odkaz na skutočný objekt a deleguje mu volania metód, pričom pridáva vlastnú logiku (napríklad logovanie, autorizácia).
// Rozhranie interface Service { void doSomething(); } // Skutočný objekt class RealService implements Service { @Override public void doSomething() { System.out.println("Skutočná akcia"); } } // Statický proxy class StaticServiceProxy implements Service { private final Service realService; public StaticServiceProxy(Service realService) { this.realService = realService; } @Override public void doSomething() { System.out.println("Pred volaním skutočnej metódy"); realService.doSomething(); System.out.println("Po volaní skutočnej metódy"); } } -
Dynamický (Dynamic Proxy): Vytvára sa počas behu pomocou Reflection API a vyžaduje, aby proxy-ovaný objekt implementoval aspoň jeden rozhranie. Umožňuje generovať proxy pre viacero tried implementujúcich rovnaké rozhranie, bez vytvárania samostatnej triedy pre každú.
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // Handler pre volania pre dynamický proxy class DynamicServiceInvocationHandler implements InvocationHandler { private final Object target; // Cieľový objekt public DynamicServiceInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Pred volaním metódy " + method.getName()); Object result = method.invoke(target, args); // Volanie metódy cieľového objektu System.out.println("Po volaní metódy " + method.getName()); return result; } } // Príklad použitia (pre rozhranie Service z príkladu statického proxy) // Service realService = new RealService(); // Service proxy = (Service) Proxy.newProxyInstance( // realService.getClass().getClassLoader(), // realService.getClass().getInterfaces(), // new DynamicServiceInvocationHandler(realService)); // proxy.doSomething(); -
CGLIB Proxy: Je založený na generovaní bajtkódu a nevyžaduje implementáciu rozhrania. Môže proxy-ovať konkrétne triedy (ak nie sú finálne a metódy nie sú finálne). Je výkonnejší ako štandardný dynamický proxy v niektorých scenároch.
// Príklad použitia CGLIB (vyžaduje externú knižnicu) // public class RealService { // public void doSomething() { // System.out.println("Skutočná akcia"); // } // } // 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("Pred volaním metódy " + method.getName()); // Object result = proxy.invokeSuper(obj, args); // Volanie metódy supertriedy (originálneho objektu) // System.out.println("Po volaní metódy " + method.getName()); // return result; // } // } // // Príklad použitia: // // Enhancer enhancer = new Enhancer(); // // enhancer.setSuperclass(RealService.class); // // enhancer.setCallback(new CglibServiceInterceptor()); // // RealService proxy = (RealService) enhancer.create(); // // proxy.doSomething();
Hlavné rozdiely:
| Typ proxy | Vyžaduje rozhranie | Generovanie | Flexibilita | Výkon | Použitie |
|---|---|---|---|---|---|
| Statický | Áno | Ručne | Nízka (pre každý triedu) | Vysoký | Jednoduché prípady, keď je štruktúra známa |
| Dynamický | Áno | Počas behu | Vysoká (pre rozhrania) | Stredný | Všeobecná logika pre rozhrania, AOP |
| CGLIB | Nie | Počas behu | Vysoká (pre triedy) | Vysoký | AOP, proxyovanie tried bez rozhraní |