Java Dynamic Proxy

Java Dynamic Proxy

Proxy mode mainly refers to providing a proxy object for the class to indirectly access the class object, and can complete some general operations in the proxy object, such as calculating the execution time for each function of the proxy object. In order to reduce code redundancy, we indirectly execute the methods in the class through proxy mode, and calculate the running time before and after execution. The proxy does not implement the method of the proxy, but only calls the method of the proxy class

Static proxy

Static proxy mainly refers to creating a proxy class and implementing the method in the interface, and calling the actual method of the proxy class in the proxy class.

Proxy class

public class Worker implements Person{
    @Override
    public String work() {
        System.out.println("worker...");
        return "worker";
    }
}

Interface

public interface Person {
    String work();
}

proxy class

public class WorkerProxy implements Person{
    private Worker worker;
    @Override
       public String work() {
        long startTime = System.currentTimeMillis();
        worker.work();//Call the actual method of the worker
        long endTime = System.currentTimeMillis();
        System.out.println("Program time:" + (endTime - startTime));
    }
}

Call proxy class

public static void main(String[] args) {
    WorkerProxy workerProxy = new workerProxy();
    workerProxy.work();
}

Dynamic agent

Static proxy in Java refers to writing a proxy class for each class statically through code. When we need to do the above operations for the methods in many classes, it will be very cumbersome, and when we use some closed source and unmodifiable code, we can't write static proxy methods for them. At this point, we use the reflection mechanism to dynamically create the proxy class when the program is running.

Implementation of dynamic agent

  • Implement the InvocationHandler interface and the invoke method. The methods calling the class will be transferred to the invoke method for execution

    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
    

    Proxy: proxy object

    Method: the method to execute

    args: parameters at execution time

  • Specify ClassLoader and interface for proxy class to create proxy class

    public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)
    

    Loader: class loader

    Interface: interface object array, which represents the interface provided to the proxy object, that is, the proxy class can call methods only after the interface of the proxy class is declared

    h:invocationHandler: indicates which InvocationHandler object the dynamic proxy object will be associated with (invoke)

  • Get the constructor of the proxied class through reflection

  • Get an instance of the proxy class and call the method

eg:

The Person interface and the Worker class do not change

proxy class

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

public class WorkHandler implements InvocationHandler {
    private Object obj;

    public WorkHandler() {
    }

    public WorkHandler(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long startTime = System.nanoTime();
        //Specifies the method of the proxied object
        Object invoke=method.invoke(obj,args);
        long endTime = System.nanoTime();
        System.out.println("Program time:" + ( (endTime - startTime) / 1000L));
        return invoke;
    }
}

Execute dynamic proxy

public class Consumer {
    public static void main(String[] args) {
        Person p=new Worker();
        //Create invocationHandler object
        InvocationHandler invocationHandler=new WorkHandler(p);
        Person proxy=(Person) Proxy.newProxyInstance(invocationHandler.getClass().getClassLoader(), p.getClass().getInterfaces(),invocationHandler);
        System.out.println(proxy.work());
    }
}

Code address

Tags: Java Dynamic Proxy

Posted on Fri, 29 Oct 2021 05:22:37 -0400 by ClevaTreva