Dynamic proxy for JAVA learning and java Dynamic proxy
Dynamic proxy in JDK1.6
In Java, a Proxy class and an InvocationHandler interface are provided under the Java. lang. reflect package. By using this class and interface, a dynamic Proxy object can be generated. The proxy provided by JDK can only act as proxy for interfaces.
Java. lang. reflect. Proxy provides static methods used to create dynamic Proxy classes and instances. It is also a superclass of all dynamic Proxy classes created by these methods.
// Method 1: This method is used to obtain the call processor public static InvocationHandler getInvocationHandler (Object proxy) associated with the specified proxy Object. // Method 2: this method is used to obtain the public static Class Object of the dynamic proxy Class associated with the specified Class loader and a group of interfaces. <?> GetProxyClass (ClassLoader loader, Class <?>... Interfaces) // method 3: This method is used to determine whether the specified Class object is a dynamic proxy Class public static boolean isProxyClass (Class <?> Cl) // Method 4: This method is used to generate a dynamic proxy instance public static Object newProxyInstance (ClassLoader loader, Class <?> [] Interfaces, InvocationHandler h)
Java. lang. reflect. InvocationHandler: calls the processor interface and customizes the invokle Method for proxy access to the real delegate class.
/** This method is used to centrally process all method calls in the dynamic proxy class. The first parameter is a proxy instance, and the second parameter is the called Method object (Method object in reflection). The third parameter is the list of parameters for calling a Method. The call Processor Pre-processes these three parameters or assigns them to the delegate class instance for launch and execution */public Object invoke (Object proxy, Method method, Object [] args) throws Throwable;
Use the newProxyInstance method in the Proxy class to create a Proxy object
Parameter: loader-defines the classloader interfaces of the proxy class-List of interfaces to be implemented by the proxy class h-specifies the call handler for method calls and returns: A proxy instance with a specified call handler with a proxy Class. It is defined by the specified Class loader and implements the specified public static Object newProxyInstance (ClassLoader loader, Class <?> [] Interfaces, InvocationHandler h) throws IllegalArgumentException
Instance
Interface:
package com.jalja.org.base.poxy;public interface ArithmeticCalculator { int add(int i, int j); int sub(int i, int j); int mul(int i, int j); int div(int i, int j);}
Implementation class:
package com.jalja.org.base.poxy;public class ArithmeticCalculatorImpl implements ArithmeticCalculator { @Override public int add(int i, int j) { int result = i + j; System.out.println("add:"+result); return result; } @Override public int sub(int i, int j) { int result = i - j; System.out.println("sub:"+result); return result; } @Override public int mul(int i, int j) { int result = i * j; System.out.println("mul:"+result); return result; } @Override public int div(int i, int j) { int result = i / j; System.out.println("div:"+result); return result; }}
Proxy and usage:
Package com.jalja.org. base. poxy. test; import java. lang. reflect. invocationHandler; import java. lang. reflect. method; import java. lang. reflect. proxy; import com.jalja.org. base. poxy. arithmeticCalculator; import com.jalja.org. base. poxy. arithmeticCalculatorImpl; public class MyInvocationHandler implements InvocationHandler {private Object target; // target Object (which Object is a dynamic proxy for) public MyInvocationHandler (Object target) {th Is.tar get = target;} @ Override/*** proxy-proxy instance on which the method is called * Method-the method Instance corresponding to the interface Method called on the proxy instance. The Method object Declaration class will be the interface in which the Method is declared. This interface can be a superinterface of the proxy interface on which the proxy class inherits the Method. * Args-an array of objects that contain the parameter values of method calls on the proxy instance. If the interface method does not use a parameter, It is null. Parameters of the basic type are encapsulated in an instance of the appropriate basic Wrapper class (such as java. lang. Integer or java. lang. Boolean. * Return-return proxy Object */public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {// obj-the Object from which the underlying method is called // args-parameters used for method calling // public Object invoke (Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException System. out. println (method. getName () + "method front ................ "); Object result = method. invoke (target, args); System. out. println ("method:" + method); System. out. println (method. the rear of the getName () + "method ................ "); Return result;} public static void main (String [] args) {/* parameter: loader-Class loader defining the proxy class interfaces-interface list to be implemented by the proxy class h-the call handler that assigns a method call returns: A proxy instance with a specified call handler of the proxy class, it is defined by the specified Class loader and implements the specified public static Object newProxyInstance (ClassLoader loader, Class <?> [] Interfaces, InvocationHandler h) throws IllegalArgumentException */ArithmeticCalculator ac = new ArithmeticCalculatorImpl (); // Object proxy = Proxy. newProxyInstance (ac. getClass (). getClassLoader (), ac. getClass (). getInterfaces (), new MyInvocationHandler (ac); ArithmeticCalculator proxy = (ArithmeticCalculator) Proxy. newProxyInstance (ac. getClass (). getClassLoader (), ac. getClass (). getInterfaces (), new MyInvocationHandler (ac); proxy. add (10,100); proxy. sub (20, 10 );}}
Cglib dynamic proxy
JDK's dynamic proxy mechanism can only implement interface classes, but does not implement JDK's dynamic proxy for classes that do not implement interfaces. cglib implements proxy for classes, the principle is to generate a subclass for the specified target class and override the method to implement enhancement. However, because the class is inherited, the final modification class cannot be proxy.
Demo:
Package com.jalja.org. base. poxy. cglib; import java. lang. reflect. method; import com.jalja.org. base. poxy. arithmeticCalculatorImpl; import net. sf. cglib. proxy. enhancer; import net. sf. cglib. proxy. methodInterceptor; import net. sf. cglib. proxy. methodProxy; public class CglibProxy implements MethodInterceptor {private Object target;/*** create proxy Object * @ param target * @ return */public Object getInstance (Object target) {this.tar get = target; Enhancer enhancer = new Enhancer (); enhancer.setSuperclass(this.tar get. getClass (); // callback method enhancer. setCallback (this); // create the proxy object return enhancer. create () ;}@ Override public Object intercept (Object obj, Method method, Object [] args, MethodProxy proxy) throws Throwable {System. out. println ("preagent"); // call the method Object result = proxy in the parent class through the proxy class. invokeSuper (obj, args); System. out. println ("post proxy"); return result;} public static void main (String [] args) {CglibProxy cglib = new CglibProxy (); ArithmeticCalculatorImpl bookCglib = (ArithmeticCalculatorImpl) cglib. getInstance (new ArithmeticCalculatorImpl (); bookCglib. add (10, 30 );}}
The performance of dynamic proxy objects created by CGLib is much higher than that of dynamic proxy objects created by JDK. However, CGLib takes much longer to create proxy objects than JDK, therefore, for single-instance objects, it is appropriate to use CGLib because they do not need to be frequently created. On the contrary, JDK is more appropriate.