Sobes.tech
Middle

What types of proxy servers do you know?

sobes.tech AI

Answer from AI

In Java, the following types of proxies exist:

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

    // 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 the proxied object to implement at least one interface. Allows generating proxies for multiple classes implementing the same interface without creating a separate class for each.

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    // Invocation handler for dynamic proxy
    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 to target method
            System.out.println("After method call " + method.getName());
            return result;
        }
    }
    
    // Usage example (for Service interface from 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 specific classes (if they are not final and methods are not final). More performant than standard dynamic proxies in some scenarios.

    // Example of using CGLIB (requires third-party 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 to superclass method (original object)
    //         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 Usage
Static Proxy Yes Manually Low (for each class) High Simple cases when structure is known
Dynamic Proxy Yes At runtime High (for interfaces) Medium Common logic for interfaces, AOP
CGLIB No At runtime High (for classes) High AOP, proxying classes without interfaces