Jaké typy proxy serverů znáte?
sobes.tech AI
Odpověď od AI
V jazyce Java existují následující typy proxy:
-
Statický (Static Proxy): Implementuje se vytvořením samostatné třídy obalovače, která obsahuje odkaz na skutečný objekt a deleguje mu volání metod, přičemž přidává vlastní logiku (například logování, autorizace).
// Rozhraní interface Service { void doSomething(); } // Skutečný objekt class RealService implements Service { @Override public void doSomething() { System.out.println("Skutečná akce"); } } // Statický proxy class StaticServiceProxy implements Service { private final Service realService; public StaticServiceProxy(Service realService) { this.realService = realService; } @Override public void doSomething() { System.out.println("Před voláním skutečné metody"); realService.doSomething(); System.out.println("Po volání skutečné metody"); } } -
Dynamický (Dynamic Proxy): Vytváří se za běhu pomocí Reflection API a vyžaduje, aby proxyovaný objekt implementoval alespoň jedno rozhraní. Umožňuje generovat proxy pro více tříd, které implementují stejné rozhraní, bez vytváření samostatné třídy pro každou.
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // Zpracovatel volání class DynamicServiceInvocationHandler implements InvocationHandler { private final Object target; // Cílový objekt public DynamicServiceInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Před voláním metody " + method.getName()); Object result = method.invoke(target, args); // Volání metody cílového objektu System.out.println("Po volání metody " + method.getName()); return result; } } // Příklad použití (pro rozhraní Service z pří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 generování bytekódu a nevyžaduje implementaci rozhraní. Může proxyovat konkrétní třídy (pokud nejsou final a metody nejsou final). V některých scénářích je výkonnější než standardní dynamické proxy.
// Příklad použití CGLIB (vyžaduje externí knihovnu) // public class RealService { // public void doSomething() { // System.out.println("Skutečná akce"); // } // } // 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("Před voláním metody " + method.getName()); // Object result = proxy.invokeSuper(obj, args); // Volání nadtřídy (originálního objektu) // System.out.println("Po volání metody " + method.getName()); // return result; // } // } // // Příklad použití: // // Enhancer enhancer = new Enhancer(); // // enhancer.setSuperclass(RealService.class); // // enhancer.setCallback(new CglibServiceInterceptor()); // // RealService proxy = (RealService) enhancer.create(); // // proxy.doSomething();
Hlavní rozdíly:
| Typ proxy | Vyžaduje rozhraní | Generace | Flexibilita | Výkon | Použití |
|---|---|---|---|---|---|
| Statický | Ano | Ručně | Nízká (pro každý třídu) | Vysoký | Jednoduché případy, struktura známá |
| Dynamický | Ano | Během běhu | Vysoká (pro rozhraní) | Střední | Obecná logika, AOP |
| CGLIB | Ne | Během běhu | Vysoká (pro třídy) | Vysoký | AOP, proxyování tříd bez rozhraní |