什麼是代理模式:
代理模式類似於買房中介,買房的一些繁雜過程你可以找人幫你代理,你直接付錢入住就行,也類是於明星的經紀人,什麼籤合同,免談之類的事情就它讓你搞定,你只需要演戲就行。
代理的架構如下:
其中代理,必須要有一個引用指向真實類。
代理模式應用場景:
安全代理:屏蔽對真是角色的訪問
遠程代理:通過代理類處理遠程方法調用
延遲加載:先加載輕量級的代理對象,真正需要的時候,再加載真實對象
代理模式有靜態代理和動態代理,動態代理有如下的實現方法:
1.JDK自帶的動態代理,常用
2.javaassist字節碼操作庫實現
3.CGLIB
4.ASM
舉例子最能說明問題:
1.靜態代理:
首先,我們來定義一個抽象接口
/**
* 抽線接口
* @author liuxg
* @date 2016年5月25日 下午4:34:40
*/
public interface Star {
void meeting() ; //開會,可以讓代理執行
void bookTicket(); //訂機票可以讓代理執行
void collectMoney(); //收錢,可以讓代理執行
void acting(); //演戲只能自己執行
}
再定義一個真實類實現抽象接口
/**
* 真是明星
*
* @author liuxg
* @date 2016年5月25日 下午5:01:35
*/
public class RealStar implements Star {
@Override
public void meeting() {
System.out.println("開會");
}
@Override
public void bookTicket() {
System.out.println("訂票");
}
@Override
public void collectMoney() {
System.out.println("收錢");
}
@Override
public void acting() {
System.out.println("演戲");
}
}
再定義一個代理類,來代理我們的realstar類,這個類需要實現抽象接口,也要有一個可以引用realstar的指針
/**
* 代理類
* @author liuxg
* @date 2016年5月25日 下午5:06:03
*/
public class ProxyStar implements Star{
private RealStar realStar;
public ProxyStar(RealStar realStar) {
this.realStar = realStar;
}
@Override
public void meeting() {
System.out.println("開會");
}
@Override
public void bookTicket() {
System.out.println("訂票");
}
@Override
public void collectMoney() {
System.out.println("收錢");
}
@Override
public void acting() {//aop編程的原理
System.out.println("代理類做一些前置操作");
realStar.acting();
System.out.println("代理類做一些後置操作");
}
}
我們寫測試類來測試
public class Client01 {
public static void main(String[] args) {
Star role = new ProxyStar(new RealStar());
role.meeting();
role.bookTicket();
role.collectMoney();
role.acting();
}
}
2.動態代理舉個例子
首先抽象接口Star 和真實的類RealStar都是一樣,但是代理類ProxyStar,我們通過JDK自帶的代理來動態生成,我們來定義一個代理類處理器
/**
* 代理類生成器
* @author liuxg
* @date 2016年5月25日 下午5:23:51
*/
public class ProxyHandler implements InvocationHandler{
RealStar realStar;
public ProxyHandler(RealStar realStar) {
this.realStar = realStar;
}
/**
* 任何調用真實角色的方法都會到這裏來
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法操作之前");
method.invoke(realStar, args);
System.out.println("方法操作之後");
return null;
}
}
然後在客戶端,我們就可以這樣子動態生成代理並調用了
public class Client01 {
public static void main(String[] args) {
ProxyHandler hander = new ProxyHandler(new RealStar());
Star star = (Star) Proxy.newProxyInstance(Client01.class.getClassLoader(), new Class[]{Star.class}, hander); //動態生成代理類
star.acting();
}
}