Sobes.tech
Middle

Koje vrste proxy servera poznajete?

sobes.tech АИ

Одговор од АИ

U Javi postoje sledeće vrste proksi:

  • Statički (Static Proxy): Implementira se kreiranjem posebne klase-omotača koja sadrži referencu na pravi objekat i delegira mu pozive metoda, pri čemu dodaje sopstvenu logiku (npr. logovanje, autorizacija).

    // Interfejs
    interface Service {
        void doSomething();
    }
    
    // Pravi objekat
    class RealService implements Service {
        @Override
        public void doSomething() {
            System.out.println("Prava radnja");
        }
    }
    
    // Statički proksi
    class StaticServiceProxy implements Service {
        private final Service realService;
    
        public StaticServiceProxy(Service realService) {
            this.realService = realService;
        }
    
        @Override
        public void doSomething() {
            System.out.println("Pre poziva pravog metoda");
            realService.doSomething();
            System.out.println("Posle poziva pravog metoda");
        }
    }
    
  • Dinamički (Dynamic Proxy): Kreira se tokom izvršenja koristeći Reflection API i zahteva da proxy-ovani objekat implementira bar jedan interfejs. Omogućava generisanje proxy-ja za više klasa koje implementiraju isti interfejs, bez kreiranja posebne klase za svaku.

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    // Handler za pozive za dinamički proxy
    class DynamicServiceInvocationHandler implements InvocationHandler {
        private final Object target; // Ciljani objekat
    
        public DynamicServiceInvocationHandler(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("Pre poziva metode " + method.getName());
            Object result = method.invoke(target, args); // Poziv metode ciljanog objekta
            System.out.println("Posle poziva metode " + method.getName());
            return result;
        }
    }
    
    // Primer korišćenja (za interfejs Service iz primera statičkog proxy-ja)
    // Service realService = new RealService();
    // Service proxy = (Service) Proxy.newProxyInstance(
    //     realService.getClass().getClassLoader(),
    //     realService.getClass().getInterfaces(),
    //     new DynamicServiceInvocationHandler(realService));
    // proxy.doSomething();
    
  • CGLIB Proxy: Baziran na generisanju bajtkoda i ne zahteva implementaciju interfejsa. Može proxy-irati konkretne klase (ako nisu finalne i metode nisu finalne). Efikasniji je od standardnog dinamičkog proxy-ja u nekim scenarijima.

    // Primer korišćenja CGLIB (zahteva spoljašnju biblioteku)
    // public class RealService {
    //     public void doSomething() {
    //         System.out.println("Prava radnja");
    //     }
    // }
    
    // 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("Pre poziva metode " + method.getName());
    //         Object result = proxy.invokeSuper(obj, args); // Poziv metode superklase (originalnog objekta)
    //         System.out.println("Posle poziva metode " + method.getName());
    //         return result;
    //     }
    // }
    
    // // Primer korišćenja:
    // // Enhancer enhancer = new Enhancer();
    // // enhancer.setSuperclass(RealService.class);
    // // enhancer.setCallback(new CglibServiceInterceptor());
    // // RealService proxy = (RealService) enhancer.create();
    // // proxy.doSomething();
    

Osnovne razlike:

Vrsta Proksija Zahteva Interfejs Generiše Fleksibilnost Performanse Primena
Statički Da Ručno Niska (za svaku klasu) Visoka Jednostavni slučajevi, kada je struktura poznata
Dinamički Da Tokom izvršenja Visoka (za interfejse) Srednja Opšte logike za interfejse, AOP
CGLIB Ne Tokom izvršenja Visoka (za klase) Visoka AOP, proxy-iranje klasa bez interfejsa