下面通過實例簡要說明,方便初步瞭解:
這裏拿數據庫請求爲例:(IDBRequest接口,DBRequest真實類,DBProxy代理)
接口:
public interface IDBRequest {
public String request();
}
真實類:
public class DBRequest implements IDBRequest{
public DBRequest(){
System.out.println("init real class!!");
try {
Thread.sleep(1000);
//數據庫連接操作等
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String request() {
return "do request";
}
}
代理類(實現延遲加載)
public class DBProxy implements IDBRequest{
private DBRequest real=null;
// protected DBProxy(){
// System.out.println("init proxy!!");
// }
@Override
public String request() {
if(real==null){
real=new DBRequest();//延遲代理,真真在使用的時候初始化等
}
return real.request();
}
}
測試類:
public class Test {
public static void main(String[] args) {
IDBRequest request=new DBProxy();//這裏不是真實初始化
request.request();//延遲加載,這裏纔是初始化
//使用動態代理生成
}
}
這裏測試沒有調用具體方法,不執行實例化對象這些操作,只有當調用方法時候才實例化對象,這就是使用代理來進行延遲加載的優點,多用於哪些初始化工作大或初始任務佔用資源的情景。
2、動態代理
動態代理是指在運行時動態生成代理類。即,代理類的字節碼將在運行時生成並載入當前代理的 ClassLoader。與靜態處理類相比,動態類有諸多好處。首先,不需要爲真實主題寫一個形式上完全一樣的封裝類,假如主題接口中的方法很多,爲每一個接口寫一個代理方法也很麻煩。如果接口有變動,則真實主題和代理類都要修改,不利於系統維護;其次,使用一些動態代理的生成方法甚至可以在運行時制定代理類的執行邏輯,從而大大提升系統的靈活性。
動態代理實現由多種方式,比如cglib javaassist或jdk自帶的
下面(jdk自帶)繼續上例子,接口和真實類就是上面的,動態代理類(DBRequestHandle)
public class DBRequestHandle implements InvocationHandler{
Object tar=null;//定義主題接口
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result=null;
result=method.invoke(tar, args);
return result;
}
public Object bind(Object tar){
this.tar=tar;
return Proxy.newProxyInstance(tar.getClass().getClassLoader(), tar.getClass().getInterfaces(), this);
}
}
實現InvocationHandler即可;主題傳入object,bind方法完成對主題對象綁定,然後具體調用invoke,這樣就完成動態代理;這樣好處是當目標方法增大時,不需要重寫多種方法,一切調用委託給動態代理完成,只需要使用方法時傳入目標對象即可。
public class Test {
public static void main(String[] args) {
//IDBRequest request=new DBProxy();//這裏不是真實初始化
//request.request();//延遲加載,這裏纔是初始化
//使用動態代理生成
DBRequestHandle proxy=new DBRequestHandle();//init proxy
IDBRequest handle=(IDBRequest)proxy.bind(new DBRequest());//綁定對象
handle.request();
}
}
看完代碼,現在我來回答,動態代理的作用是什麼:
Proxy類的代碼量被固定下來,不會因爲業務的逐漸龐大而龐大;
可以實現AOP編程,實際上靜態代理也可以實現,總的來說,AOP可以算作是代理模式的一個典型應用;
解耦,通過參數就可以判斷真實類,不需要事先實例化,更加靈活多變。