Proxy

13 Sep 2024 . java .


Static Proxy

  1. Define an interface and its implementation class.
  2. Creating a proxy class also implements this interface.
  3. Inject the target object into the proxy class.

Example:

Interface to send message

public interface SmsService {
    String send(String message);
}

Implement the interface

public class SmsServiceImpl implements SmsService {
    public String send(String message) {
        System.out.println("send message:" + message);
        return message;
    }
}

Create the proxy class also implementing the interface

public class SmsProxy implements SmsService {

    private final SmsService smsService;

    public SmsProxy(SmsService smsService) {
        this.smsService = smsService;
    }

    @Override
    public String send(String message) {
                System.out.println("before method send()");
        smsService.send(message);
                System.out.println("after method send()");
        return null;
    }
}

In practice

public class Main {
    public static void main(String[] args) {
        SmsService smsService = new SmsServiceImpl();
        SmsProxy smsProxy = new SmsProxy(smsService);
        smsProxy.send("java");
    }
}


Dynamic Proxy

  1. Define an interface and its implementation class
  2. Customize InvocationHandler and override the invoke method. In the invoke method, we will call the native method and customize some processing logic.
  3. Create proxy object by Proxy.newProxyInstance (ClassLoader loader,Class<? >[] interfaces,InvocationHandler h)

Example:

Interface to send message

public interface SmsService {
    String send(String message);
}

Implement the interface

public class SmsServiceImpl implements SmsService {
    public String send(String message) {
        System.out.println("send message:" + message);
        return message;
    }
}

Define InvocationHandler

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class DebugInvocationHandler implements InvocationHandler {
        private final Object target;

    public DebugInvocationHandler(Object target) {
        this.target = target;
}

public Object invoke(Object proxy, Method method, Object[] args) throws 
InvocationTargetException, IllegalAccessException {
                System.out.println("before method " + method.getName());
        Object result = method.invoke(target, args);
                System.out.println("after method " + method.getName());
        return result;
    }
}

Create Proxy object

public class JdkProxyFactory {
    public static Object getProxy(Object target) {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                                new DebugInvocationHandler(target)
                            );
    }
}

In practice

SmsService smsService = (SmsService) JdkProxyFactory.getProxy(
new SmsServiceImpl());
smsService.send("java"); //call invoke()