1、靜態代理java
一、經過繼承實現代理數組
二、經過實現相同的接口進行代理dom
例:ide
接口this
//統一接口 public interface Moveable { public void move(); }
被代理類spa
import java.util.Random; public class Car implements Moveable{ @Override public void move() { try { Thread.sleep(new Random().nextInt(1000)); System.out.println("汽車正在行駛中....."); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
代理類1代理
public class CarLogProxy implements Moveable { private Moveable m; public CarLogProxy(Moveable m) { super(); this.m = m; } @Override public void move() { System.out.println("日誌開始。。。。。"); m.move(); System.out.println("日誌結束。。。。。"); } }
代理類2日誌
public class CarTimeProxy implements Moveable { private Moveable m; public CarTimeProxy(Moveable m) { super(); this.m = m; } @Override public void move() { long starttime = System.currentTimeMillis(); System.out.println("汽車開始行駛。。。。。"); m.move(); long endtime = System.currentTimeMillis(); System.out.println("汽車行駛結束。。。。。行駛時間("+(endtime - starttime)+")"); } }
客戶端code
public class Client { public static void main(String[] args) { Car car = new Car(); Moveable m = new CarTimeProxy(car); Moveable m1 = new CarLogProxy(m); m1.move(); } }
2、動態代理 (JDK動態代理)對象
Java動態代理類位於java.lang.reflect包下,通常主要涉及到如下兩個類:
(1) Interface InvocationHandler:該類中僅定義了一個方法
public object invoke(Object obj, Method method, Object[] args)
第一個參數obj通常是指代理類,method是被代理的方法,
args爲該方法的參數數組。這個抽象方法在代理類中動態實現。
(2) Proxy:該類即爲動態代理類
static Object newProxyInstance(ClassLoader loader, Class[] interfaces,
InvocationHandler h):返回代理類的一個實例,返回後的代理類能夠看成
被代理類使用(可以使用被代理類的在接口中聲明過的方法)
例:
接口
//統一接口 public interface Moveable { public void move(); }
被代理類
import java.util.Random; public class Car implements Moveable{ @Override public void move() { try { Thread.sleep(new Random().nextInt(1000)); System.out.println("汽車正在行駛中....."); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
動態代理handler
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class TimeHandler implements InvocationHandler { public TimeHandler(Object target) { super(); this.target = target; } private Object target; /* * 參數: * proxy 被代理對象 * method 被代理對象的方法 * args 方法的參數 * * 返回值: * Object 方法的返回值 */ @Override public Object invoke(Object proxy, Method method, Object[] arg) throws Throwable { long starttime = System.currentTimeMillis(); System.out.println("汽車開始行駛。。。。。"); method.invoke(target); long endtime = System.currentTimeMillis(); System.out.println("汽車行駛結束。。。。。行駛時間("+(endtime - starttime)+")"); return null; } }
客戶端代碼
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { Car car = new Car(); InvocationHandler h = new TimeHandler(car); Class<?> cls = car.getClass(); /** * loader 類加載器 * interfaces 實現接口 * h InvocationHandler */ Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h); m.move(); } }
所謂Dynamic Proxy是這樣一種class:
它是在運行時生成的class
該class須要實現一組interface
使用動態代理類時,必須實現InvocationHandler接口
步驟:
一、建立一個實現接口InvocationHandler的類,它必須實現invoke方法。
二、建立被代理的類以及接口
三、調用Proxy的靜態方法,建立一個代理類
newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
四、經過代理調用方法
CGLIB動態代理
一、導入cglib包
二、代理類實現 net.sf.cglib.proxy.MethodInterceptor接口
三、代理類實現 intercept(Object obj, Method m, Object[] args, MethodProxy proxy) 方法。
被代理類
public class Train { public void move() { System.out.println("火車行駛中......"); } }
代理類
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) { //設置建立子類的類 enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } /** * 攔截全部目標類方法的調用 * obj 目標類的實例 * m 目標方法的反射對象 * args 方法的參數 * proxy 代理類的實例 */ @Override public Object intercept(Object obj, Method m, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("日誌開始...."); //代理類調用父類的方法 proxy.invokeSuper(obj, args); System.out.println("日誌結束...."); return null; } }
客戶端
public class Client { public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); Train t = (Train)proxy.getProxy(Train.class); t.move(); } }
JDK動態代理
一、只能代理實現了接口的類
二、沒有實現接口的類不能實現JDK動態代理
CGLIB動態代理
一、針對類來實現代理的。
二、對指定目標產生一個子類,經過方法攔截技術攔截全部父類方法的調用。