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()); } }