Sobes.tech
Middle

Kokius proxy serverių tipus žinote?

sobes.tech AI

Atsakymas iš AI

Java egzistuoja šios rūšys proxy:

  • Statinis (Static Proxy): Įgyvendinamas sukuriant atskirą apvalkalo klasę, kuri turi nuorodą į tikrąjį objektą ir deleguoja jam metodų iškvietimus, pridėdama savo logiką (pvz., žurnalavimą, autorizaciją).

    // Sąsaja
    interface Service {
        void doSomething();
    }
    
    // Tikrasis objektas
    class RealService implements Service {
        @Override
        public void doSomething() {
            System.out.println("Tikras veiksmas");
        }
    }
    
    // Statinis proxy
    class StaticServiceProxy implements Service {
        private final Service realService;
    
        public StaticServiceProxy(Service realService) {
            this.realService = realService;
        }
    
        @Override
        public void doSomething() {
            System.out.println("Prieš kviečiant tikrą metodą");
            realService.doSomething();
            System.out.println("Po kviečiant tikrą metodą");
        }
    }
    
  • Dinaminis (Dynamic Proxy): Sukuriamas vykdymo metu naudojant Reflection API ir reikalauja, kad proxy objektas įgyvendintų bent vieną sąsają. Leidžia generuoti proxy daugeliui klasių, įgyvendinančių tą patį sąsają, be atskiros klasės kiekvienam.

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    // Kviečiančiojo apdorotojas dinamiškam proxy
    class DynamicServiceInvocationHandler implements InvocationHandler {
        private final Object target; // Tikslinis objektas
    
        public DynamicServiceInvocationHandler(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("Prieš metodo kvietimą " + method.getName());
            Object result = method.invoke(target, args); // Tikslinio objekto metodo iškvietimas
            System.out.println("Po metodo kvietimo " + method.getName());
            return result;
        }
    }
    
    // Pavyzdys naudojimo (sąsajai Service iš statinio proxy pavyzdžio)
    // Service realService = new RealService();
    // Service proxy = (Service) Proxy.newProxyInstance(
    //     realService.getClass().getClassLoader(),
    //     realService.getClass().getInterfaces(),
    //     new DynamicServiceInvocationHandler(realService));
    // proxy.doSomething();
    
  • CGLIB Proxy: Pagrįstas baitkodo generavimu ir nereikalauja įgyvendinti sąsajos. Gali proxy konkrečius klases (jei jos nėra finalinės ir metodai nėra finaliniai). Kai kuriais atvejais yra efektyvesnis nei standartinis dinaminis proxy.

    // Pavyzdys naudojimo su CGLIB (reikalauja trečiosios šalies bibliotekos)
    // public class RealService {
    //     public void doSomething() {
    //         System.out.println("Tikras veiksmas");
    //     }
    // }
    
    // 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("Prieš metodo kvietimą " + method.getName());
    //         Object result = proxy.invokeSuper(obj, args); // Superklasės metodo iškvietimas (originalus objektas)
    //         System.out.println("Po metodo kvietimo " + method.getName());
    //         return result;
    //     }
    // }
    
    // // Pavyzdys naudojimo:
    // // Enhancer enhancer = new Enhancer();
    // // enhancer.setSuperclass(RealService.class);
    // // enhancer.setCallback(new CglibServiceInterceptor());
    // // RealService proxy = (RealService) enhancer.create();
    // // proxy.doSomething();
    

Pagrindiniai skirtumai:

Proxy tipas Reikalauja sąsajos Generavimas Lankstumas Našumas Taikymas
Statinis Taip Rankiniu būdu Mažas (kiekvienam klasiui) Aukštas Paprasti atvejai, kai struktūra žinoma
Dinaminis Taip Vykdymo metu Aukštas (sąsajoms) Vidutinis Bendroji logika sąsajoms, AOP
CGLIB Nėra Vykdymo metu Aukštas (klasėms) Aukštas AOP, proxy klasių be sąsajų naudojimas