Sobes.tech
Middle

Milliseid proxy-serverite tüüpe te tead?

sobes.tech AI

Vastus AI-lt

Java-s on järgmised proxy tüübid:

  • Statiline (Static Proxy): Rakendatakse, luues eraldi katteklassi, mis sisaldab viidet tegelikule objekti ja edastab talle meetodite kutsed, lisades oma loogika (nt logimine, autoriseerimine).

    // Liides
    interface Service {
        void doSomething();
    }
    
    // Tõeline objekt
    class RealService implements Service {
        @Override
        public void doSomething() {
            System.out.println("Tõeline tegevus");
        }
    }
    
    // Statiline proxy
    class StaticServiceProxy implements Service {
        private final Service realService;
    
        public StaticServiceProxy(Service realService) {
            this.realService = realService;
        }
    
        @Override
        public void doSomething() {
            System.out.println("Enne tõelise meetodi kutsumist");
            realService.doSomething();
            System.out.println("Pärast tõelise meetodi kutsumist");
        }
    }
    
  • Dünaamiline (Dynamic Proxy): Loobub jooksvalt Reflection API kasutades ja nõuab, et proxy objekt rakendaks vähemalt ühte liidest. Võimaldab genereerida proxy mitmele klassile, mis rakendavad sama liidest, ilma eraldi klassita igaüks.

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    // Kutsuja käsitleja dünaamilistele proxy-dele
    class DynamicServiceInvocationHandler implements InvocationHandler {
        private final Object target; // Sihtobjekt
    
        public DynamicServiceInvocationHandler(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("Enne meetodi kutsumist " + method.getName());
            Object result = method.invoke(target, args); // Sihtobjekti meetodi kutsumine
            System.out.println("Pärast meetodi kutsumist " + method.getName());
            return result;
        }
    }
    
    // Näide kasutamisest (vastavalt statilise proxy näidisele Service liidese puhul)
    // Service realService = new RealService();
    // Service proxy = (Service) Proxy.newProxyInstance(
    //     realService.getClass().getClassLoader(),
    //     realService.getClass().getInterfaces(),
    //     new DynamicServiceInvocationHandler(realService));
    // proxy.doSomething();
    
  • CGLIB Proxy: Põhineb baitkoodi genereerimisel ega nõua liidese rakendamist. Võib proxy konkreetseid klasse (kui need ei ole final ja meetodid ei ole final). Mõnel juhul on see kiirem kui standardne dünaamiline proxy.

    // Näide CGLIB kasutamisest (vajab kolmanda osapoole teeki)
    // public class RealService {
    //     public void doSomething() {
    //         System.out.println("Tõeline tegevus");
    //     }
    // }
    
    // 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("Enne meetodi kutsumist " + method.getName());
    //         Object result = proxy.invokeSuper(obj, args); // Superklassi meetod (originaalobjekt)
    //         System.out.println("Pärast meetodi kutsumist " + method.getName());
    //         return result;
    //     }
    // }
    
    // // Näide kasutamisest:
    // // Enhancer enhancer = new Enhancer();
    // // enhancer.setSuperclass(RealService.class);
    // // enhancer.setCallback(new CglibServiceInterceptor());
    // // RealService proxy = (RealService) enhancer.create();
    // // proxy.doSomething();
    

Peamised erinevused:

Proxy tüüp Nõuab liidest Generatsioon Paindlikkus Tõhusus Rakendus
Statiline Jah Käsitsi Madal (üksiklassi jaoks) Kõrge Lihtsad juhtumid, kui struktuur on teada
Dünaamiline Jah Käivituse ajal Kõrge (liideste jaoks) Keskmine Üldine loogika liideste jaoks, AOP
CGLIB Ei Käivituse ajal Kõrge (klassidele) Kõrge AOP, proxy klassid ilma liidesteta