Ce tipuri de servere proxy cunoști?
sobes.tech AI
Răspuns de la AI
În Java, există următoarele tipuri de proxy-uri:
-
Proxy static (Static Proxy): Se implementează prin crearea unei clase wrapper separate, care conține o referință la obiectul real și delegă apelurile de metode către acesta, adăugând propria logică (de exemplu, logare, autentificare).
// Interfață interface Service { void doSomething(); } // Obiect real class RealService implements Service { @Override public void doSomething() { System.out.println("Acțiune reală"); } } // Proxy static class StaticServiceProxy implements Service { private final Service realService; public StaticServiceProxy(Service realService) { this.realService = realService; } @Override public void doSomething() { System.out.println("Înainte de apelarea metodei reale"); realService.doSomething(); System.out.println("După apelarea metodei reale"); } } -
Proxy dinamic (Dynamic Proxy): Se creează în timpul execuției folosind Reflection API și necesită ca obiectul proxyat să implementeze cel puțin o interfață. Permite generarea de proxy-uri pentru mai multe clase care implementează aceeași interfață, fără a crea o clasă separată pentru fiecare.
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // Handler pentru apeluri de metode class DynamicServiceInvocationHandler implements InvocationHandler { private final Object target; // Obiect țintă public DynamicServiceInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Înainte de apelarea metodei " + method.getName()); Object result = method.invoke(target, args); // Apelarea metodei pe obiectul țintă System.out.println("După apelarea metodei " + method.getName()); return result; } } // Exemplu de utilizare (pentru interfața Service din exemplul proxy-ului static) // Service realService = new RealService(); // Service proxy = (Service) Proxy.newProxyInstance( // realService.getClass().getClassLoader(), // realService.getClass().getInterfaces(), // new DynamicServiceInvocationHandler(realService)); // proxy.doSomething(); -
Proxy CGLIB: Se bazează pe generarea de bytecode și nu necesită implementarea unei interfețe. Poate proxy-iza clase concrete (dacă nu sunt finale și metodele nu sunt finale). Este mai performant decât proxy-urile dinamice standard în anumite scenarii.
// Exemplu de utilizare CGLIB (necesită bibliotecă externă) // public class RealService { // public void doSomething() { // System.out.println("Acțiune reală"); // } // } // 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("Înainte de apelarea metodei " + method.getName()); // Object result = proxy.invokeSuper(obj, args); // Apelarea metodei superclasei (obiectul original) // System.out.println("După apelarea metodei " + method.getName()); // return result; // } // } // // Exemplu de utilizare: // // Enhancer enhancer = new Enhancer(); // // enhancer.setSuperclass(RealService.class); // // enhancer.setCallback(new CglibServiceInterceptor()); // // RealService proxy = (RealService) enhancer.create(); // // proxy.doSomething();
Principalele diferențe:
| Tip Proxy | Necesită Interfață | Generare | Flexibilitate | Performanță | Aplicație |
|---|---|---|---|---|---|
| Static | Da | Manual | Scăzut (pentru fiecare clasă) | Ridicată | Cazuri simple, structura cunoscută |
| Dinamic | Da | În timpul execuției | Ridicată (pentru interfețe) | Medie | Logică comună pentru interfețe, AOP |
| CGLIB | Nu | În timpul execuției | Ridicată (pentru clase) | Ridicată | AOP, proxy pentru clase fără interfețe |