Previously, I learned the proxy mode of Java, and I was deeply impressed by how wonderful this mode is!A simple tidy up for later viewing.
Definition: Provides a proxy for other objects to control access to this object.(e.g. train ticket agent point)
Classification:
Remote Agent
Virtual Agent
Protection Agent
Smart Reference Agent
Smart Reference Agent
Static Proxy
The proxy and the proxy object are determined before they are proxied.They all implement the same interface or inherit the same abstract class.
Two implementations: inheritance (not recommended) and aggregation
Dynamic Proxy
jdk dynamic proxy
1. Only classes that implement interfaces can be proxied
2. Classes that do not implement interfaces cannot implement jdk's dynamic proxy.
CGLIB Dynamic Proxy
1. Implementing proxy against classes
2. Produce a subclass of the specified target class, intercepting all calls to parent methods through method interception techniques
jdk dynamic proxy
Key: ProxyHandler Transaction Processor
Steps to achieve:
1. Create a class that implements the interface InvocationHandler, which must implement the invoke method
2. Create proxied classes and interfaces
3. Call Proxy's static method to create a proxy class
newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
4. Call methods through proxy
Sample Code: (Simulate Time Recording and Logging Dynamic Agent, Simple and Clear)
package com.jdkproxy; /** * Interface implemented by proxy class * @author Administrator */ public interface Moveable { public void move(); }
package com.jdkproxy; import java.util.Random; /** * Proxy Class * @author Administrator */ public class Car implements Moveable { @Override public void move() { // Realize driving try { Thread.sleep(new Random().nextInt(1000)); System.out.println("The car is running."); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package com.jdkproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Pattern Implementation Log Logging Agent Class * @author Administrator */ public class LogProxy implements InvocationHandler { private Object target; public LogProxy(Object target) { super(); this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Logging Start"); method.invoke(target); System.out.println("Logging End"); return null; } }
package com.jdkproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * Schema implementation Time record proxy class * @author Administrator * */ public class TimeHandler implements InvocationHandler { private Object target; public TimeHandler(Object target) { super(); this.target = target; } /** * Parameters: * proxy: Proxy Object * method: Method of Proxy Object * args: Parameters of the method * * Return value * Object Return value of method */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long starttime = System.currentTimeMillis(); System.out.println("The car is starting to run."); method.invoke(target); long endtime = System.currentTimeMillis(); System.out.println("The car is over.Car travel time" + (endtime - starttime) + "Millisecond"); return null; } }
CGLIB Dynamic Proxypackage com.jdkproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import com.proxy.Car; import com.proxy.Moveable; /** * jdk Dynamic Proxy Test Class * @author Administrator * */ public class Test { public static void main(String[] args) { Car car = new Car(); InvocationHandler h = new TimeHandler(car); Class<?> cls = car.getClass(); /** * loader classloader * interfaces Implement Interface * h InvocationHandler */ //Add Time Agent Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h); //Add Log Agent InvocationHandler h1 = new LogProxy(m); Moveable m2 = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h1); m2.move(); } }
Produces a subclass of the specified target class and intercepts calls to all parent methods through method interception techniques.
Code example:
package com.cglib; public class Train { public void move(){ System.out.println("The train is running."); } }
package com.cglib; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz){ //Set the class for which the subclass is created (for which class the proxy class is generated) enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } /** * Intercept calls to all target class methods * Parameters: * obj Instances of the target class * m Reflected object of target method * args Parameters of the method * proxy Instances of proxy classes */ @Override public Object intercept(Object obj, Method m, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("Log Start"); //Proxy class calls parent class's methods proxy.invokeSuper(obj, args); System.out.println("Log End"); return null; } }
Simulate the implementation of the JDK dynamic proxy and record it later.package com.cglib; public class Client { public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); Train t = (Train) proxy.getProxy(Train.class); t.move(); } }