Quali tipi di server proxy conosci?
sobes.tech AI
Risposta dell'AI
In Java, ci sono i seguenti tipi di proxy:
-
Proxy Statico (Static Proxy): Si implementa creando una classe wrapper separata che contiene un riferimento all'oggetto reale e delega le chiamate ai suoi metodi, aggiungendo la propria logica (ad esempio, logging, autorizzazione).
// Interfaccia interface Service { void doSomething(); } // Oggetto reale class RealService implements Service { @Override public void doSomething() { System.out.println("Azione reale"); } } // Proxy statico class StaticServiceProxy implements Service { private final Service realService; public StaticServiceProxy(Service realService) { this.realService = realService; } @Override public void doSomething() { System.out.println("Prima di chiamare il metodo reale"); realService.doSomething(); System.out.println("Dopo aver chiamato il metodo reale"); } } -
Proxy Dinamico (Dynamic Proxy): Creato in fase di esecuzione usando Reflection API e richiede che l'oggetto proxy implementi almeno un'interfaccia. Permette di generare proxy per più classi che implementano un'interfaccia, senza creare una classe separata per ciascuna.
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // Handler per chiamate di proxy dinamico class DynamicServiceInvocationHandler implements InvocationHandler { private final Object target; // Oggetto target public DynamicServiceInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Prima di chiamare il metodo " + method.getName()); Object result = method.invoke(target, args); // Chiamata al metodo dell'oggetto target System.out.println("Dopo aver chiamato il metodo " + method.getName()); return result; } } // Esempio di utilizzo (per l'interfaccia Service del proxy statico) // Service realService = new RealService(); // Service proxy = (Service) Proxy.newProxyInstance( // realService.getClass().getClassLoader(), // realService.getClass().getInterfaces(), // new DynamicServiceInvocationHandler(realService)); // proxy.doSomething(); -
Proxy CGLIB: Basato sulla generazione di bytecode e non richiede l'implementazione di un'interfaccia. Può proxyare classi concrete (se non sono finali e i metodi non sono finali). È più performante rispetto al proxy dinamico standard in alcuni scenari.
// Esempio di utilizzo di CGLIB (richiede libreria esterna) // public class RealService { // public void doSomething() { // System.out.println("Azione reale"); // } // } // 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("Prima di chiamare il metodo " + method.getName()); // Object result = proxy.invokeSuper(obj, args); // Chiamata del metodo della superclasse (oggetto originale) // System.out.println("Dopo aver chiamato il metodo " + method.getName()); // return result; // } // } // // Esempio di utilizzo: // // Enhancer enhancer = new Enhancer(); // // enhancer.setSuperclass(RealService.class); // // enhancer.setCallback(new CglibServiceInterceptor()); // // RealService proxy = (RealService) enhancer.create(); // // proxy.doSomething();
Principali differenze:
| Tipo di Proxy | Richiede Interfaccia | Generazione | Flessibilità | Prestazioni | Applicazione |
|---|---|---|---|---|---|
| Statico | Sì | Manuale | Bassa (per ogni classe) | Alta | Casi semplici, struttura nota |
| Dinamico | Sì | In fase di esecuzione | Alta (per interfacce) | Media | Logica comune per interfacce, AOP |
| CGLIB | No | In fase di esecuzione | Alta (per classi) | Alta | AOP, proxy di classi senza interfacce |