Sobes.tech
Middle

Milyen típusú proxy szervereket ismersz?

sobes.tech MI

Válasz az MI-től

Java-ban a következő proxy típusok léteznek:

  • Statikus (Static Proxy): Külön osztályburkoló létrehozásával valósul meg, amely tartalmazza a valódi objektum hivatkozását, és delegálja neki a metódushívásokat, miközben saját logikát ad hozzá (pl. naplózás, hitelesítés).

    // Interfész
    interface Service {
        void doSomething();
    }
    
    // Valódi objektum
    class RealService implements Service {
        @Override
        public void doSomething() {
            System.out.println("Valódi művelet");
        }
    }
    
    // Statikus proxy
    class StaticServiceProxy implements Service {
        private final Service realService;
    
        public StaticServiceProxy(Service realService) {
            this.realService = realService;
        }
    
        @Override
        public void doSomething() {
            System.out.println("A valódi metódus hívása előtt");
            realService.doSomething();
            System.out.println("A valódi metódus hívása után");
        }
    }
    
  • Dinamikus (Dynamic Proxy): A Reflection API segítségével futásidőben jön létre, és megköveteli, hogy a proxyzott objektum legalább egy interfészt megvalósítson. Lehetővé teszi, hogy több osztályhoz generáljunk proxy-t, amelyek ugyanazt az interfészt valósítják meg, anélkül, hogy mindenhez külön osztályt kellene írni.

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    // A hívások kezelésére szolgáló osztály
    class DynamicServiceInvocationHandler implements InvocationHandler {
        private final Object target; // Célobjektum
    
        public DynamicServiceInvocationHandler(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("Metódus hívása előtt " + method.getName());
            Object result = method.invoke(target, args); // Metódus hívása a célobjéken
            System.out.println("Metódus hívása után " + method.getName());
            return result;
        }
    }
    
    // Használati példa (a statikus proxy példájából a Service interfészhez)
    // Service realService = new RealService();
    // Service proxy = (Service) Proxy.newProxyInstance(
    //     realService.getClass().getClassLoader(),
    //     realService.getClass().getInterfaces(),
    //     new DynamicServiceInvocationHandler(realService));
    // proxy.doSomething();
    
  • CGLIB Proxy: Bytecode generálásra épül, és nem igényel interfész megvalósítást. Konkrét osztályokat proxyzhat (ha nem final és a metódusok sem finalok). Bizonyos esetekben gyorsabb, mint a standard dinamikus proxy.

    // CGLIB használati példa (külső könyvtár szükséges)
    // public class RealService {
    //     public void doSomething() {
    //         System.out.println("Valódi művelet");
    //     }
    // }
    
    // 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("Metódus hívása előtt " + method.getName());
    //         Object result = proxy.invokeSuper(obj, args); // Eredeti osztály metódusának hívása
    //         System.out.println("Metódus hívása után " + method.getName());
    //         return result;
    //     }
    // }
    
    // // Használati példa:
    // // Enhancer enhancer = new Enhancer();
    // // enhancer.setSuperclass(RealService.class);
    // // enhancer.setCallback(new CglibServiceInterceptor());
    // // RealService proxy = (RealService) enhancer.create();
    // // proxy.doSomething();
    

Fő különbségek:

Proxy típus Igényel Interfészt Generálás Rugalmasság Teljesítmény Alkalmazás
Statikus Igen Kézi Alacsony (minden osztálynál) Magas Egyszerű esetek, szerkezet ismert
Dinamikus Igen Futásidő Magas (interfészekhez) Közepes Általános logika, AOP
CGLIB Nem Futásidő Magas (osztályokhoz) Magas AOP, osztály proxyzása interfész nélkül