Sobes.tech
Middle

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