Sobes.tech
Middle

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 Manuale Bassa (per ogni classe) Alta Casi semplici, struttura nota
Dinamico 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