Sobes.tech
Middle

Ποιοι τύποι διακομιστών proxy γνωρίζετε;

sobes.tech AI

Απάντηση από AI

In Java, the following types of proxies exist:

  • Static Proxy: Implemented by creating a separate wrapper class that holds a reference to the real object and delegates method calls to it, adding its own logic (e.g., logging, authentication).

    // Interface
    interface Service {
        void doSomething();
    }
    
    // Real object
    class RealService implements Service {
        @Override
        public void doSomething() {
            System.out.println("Real action");
        }
    }
    
    // Static proxy
    class StaticServiceProxy implements Service {
        private final Service realService;
    
        public StaticServiceProxy(Service realService) {
            this.realService = realService;
        }
    
        @Override
        public void doSomething() {
            System.out.println("Before calling the real method");
            realService.doSomething();
            System.out.println("After calling the real method");
        }
    }
    
  • Dynamic Proxy: Created at runtime using Reflection API and requires that the proxied object implements at least one interface. Allows generating proxies for multiple classes implementing the same interface without creating separate classes for each.

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    // Handler for method calls
    class DynamicServiceInvocationHandler implements InvocationHandler {
        private final Object target; // Target object
    
        public DynamicServiceInvocationHandler(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("Before method call " + method.getName());
            Object result = method.invoke(target, args); // Call method on target object
            System.out.println("After method call " + method.getName());
            return result;
        }
    }
    
    // Usage example (for the Service interface from the static proxy example)
    // Service realService = new RealService();
    // Service proxy = (Service) Proxy.newProxyInstance(
    //     realService.getClass().getClassLoader(),
    //     realService.getClass().getInterfaces(),
    //     new DynamicServiceInvocationHandler(realService));
    // proxy.doSomething();
    
  • CGLIB Proxy: Based on bytecode generation and does not require interface implementation. Can proxy concrete classes (if they are not final and methods are not final). It is more performant than standard dynamic proxies in some scenarios.

    // CGLIB usage example (requires external library)
    // public class RealService {
    //     public void doSomething() {
    //         System.out.println("Real action");
    //     }
    // }
    
    // 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("Before method call " + method.getName());
    //         Object result = proxy.invokeSuper(obj, args); // Call original method
    //         System.out.println("After method call " + method.getName());
    //         return result;
    //     }
    // }
    
    // // Usage example:
    // // Enhancer enhancer = new Enhancer();
    // // enhancer.setSuperclass(RealService.class);
    // // enhancer.setCallback(new CglibServiceInterceptor());
    // // RealService proxy = (RealService) enhancer.create();
    // // proxy.doSomething();
    

Main differences:

Proxy Type Requires Interface Generation Flexibility Performance Application
Static Yes Manual Low (per class) High Simple cases, structure known
Dynamic Yes Runtime High (for interfaces) Medium Common logic for interfaces, AOP
CGLIB No Runtime High (for classes) High AOP, proxying classes without interfaces