Creating a proxy object runtime steps
- Generate the proxy class bytecode
- Load byte code, create a proxy object
First, the purpose is not only to achieve the proxy object methods are proxy object when the method is called, but also can increase the method they want to perform, naturally be to get a proxy object
Agent class needs to implement the interface class of the proxy object, the proxy object thus generated may be executed by calling the method proxy object. Thus, the need to create the proxy class is an interface class proxy object (reflection obtained)
Proxy class interface methods implemented by the user into a custom method in a class, and therefore need to get the proxy class class (or set constructor method) The user-defined
Since the byte code to be loaded, it must obtain classLoader, may be obtained by the reflection from the proxy object.
Thus a method for generating a proxy object
// target for the proxy object
public <T> T The getProxy () { return (T) the Proxy.newProxyInstance (target.getClass (). getClassLoader (), // class loader for loading proxy class bytecode generated
target.getClass (). getInterfaces () // need to implement the interface proxy class to be the class of the proxy object
the this // user agent implemented method defined
); }
the above is a complete implementation of the following codes taken full dynamic proxy implementation example is as follows:
taken
JDK dynamic proxy implementation principle
com.lnjecit.proxy Package; / ** * the Subject * abstract relating to the interface * @author * @Create 2018-03-29 14:16 ** / public interface the Subject { void doSomething (); }
And an interface to create a new implementation class RealSubject RealSubject
/** * RealSubject * 真实主题类 * @author * @create 2018-03-29 14:21 **/ public class RealSubject implements Subject { @Override public void doSomething() { System.out.println("RealSubject do something"); } }
Then create a proxy class JDKDynamicProxy achieve java.lang.reflect.InvocationHandler interface rewrite invoke method
com.lnjecit.proxy.dynamic.jdk Package Penalty for; Import java.lang.reflect.InvocationHandler; Import java.lang.reflect.Method; Import java.lang.reflect.Proxy; / ** * JDKDynamicProxy * jdkd dynamic proxy * * @ author * @Create 2018-03-29 16:17 ** / public class JDKDynamicProxy the implements of InvocationHandler { Private Object target; public JDKDynamicProxy (Object target) { this.target = target; } / ** * Gets the interface proxy object instance * @param <T> * @return * / public <T> T getProxy() { return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Do something before"); Object result = method.invoke(target, args); System.out.println("Do something after"); return result; } }
New Test class Client Test Results
com.lnjecit.proxy Package; Import com.lnjecit.proxy.dynamic.jdk.JDKDynamicProxy; / ** * Client * Client test code * * @author * @Create 2018-03-29 14:26 ** / public class Client { public static void main (String [] args) { // save the generated proxy class bytecode files System.getProperties () PUT ( "sun.misc.ProxyGenerator.saveGeneratedFiles", "to true");. // JDK dynamic test agent . JDKDynamicProxy the Subject Subject new new = (new new RealSubject ()) The getProxy (); subject.doSomething (); } }
Output:
Do something before
RealSubject do something
Do something after