一、動態(tài)代理的作用
- 什么是代理
代理模式的意圖是通過提供一個代理( Proxy )或者占位符來控制對該對象的訪問。
- 使用的場景
在我們生活中,代理也是隨處可見,其中中介就是一個很好的例子,把代理看做生活中的中介,將更加易于理解,試想一下,如果我們想租房或者買房的話通過中間是不是就可以讓我們非常省心。
二、靜態(tài)代理
在java中又兩種代理模型,稱之為靜態(tài)代理和動態(tài)代理。為了保證與所代理的對象功能行為的一致性,代理類一般需要實現(xiàn)實體類所實現(xiàn)的同一個接口,以下即為一個最基本的代理模式的結構。
首先提供一個接口供實體類和代理類實現(xiàn)。
/**
* Created by jiangcheng on 2017/11/19.
*
* 抽象接口
*/
public interface Subject {
// 統(tǒng)一行為
void doSomeThing();
}
實體類:
public class RealSubject implements Subject {
@Override
public void doSomeThing() {
System.out.println(" RealSubject do somethings ");
}
}
代理類:
public class SubjectProxy implements Subject {
private RealSubject mRealSubject;
public SubjectProxy(RealSubject realSubject) {
mRealSubject = realSubject;
}
@Override
public void doSomeThing() {
// 這里就是所謂的aop 面向切面編程了, 你可以在調用實際功能之前或者之后做一些額外的處理
System.out.println(" RealSubject do somethings before");
mRealSubject.doSomeThing();
System.out.println(" RealSubject do somethings after");
}
}
測試類:
public class TestProxy {
public static void main(String args[]) {
Subject sub = new SubjectProxy(new RealSubject());
sub.doSomeThing();
}
}
結果:

從上面的例子可以看到調用的時候我們對實體類做了一層封裝,從代碼角度看,反而實現(xiàn)上更加復雜了,沒有體現(xiàn)出代理模式的優(yōu)勢,其實代理模式的作用就是通過代理對象控制實體對象的訪問,從而提高訪問的安全性,而且可以在調用實體類的方法時做一些預處理和善后的工作,就是所謂的aop(面向切面編程)。這樣就保證了實體類可以拋開復雜的業(yè)務邏輯而只去實現(xiàn)一些最純粹的功能,提高了代碼的可讀性和靈活性。
三、動態(tài)代理
這個才是今天的重點,我們可以想一下,萬一實現(xiàn)Subject接口的實體類不止一個呢,是不是需要創(chuàng)建SubjectProxy1、SubjectProxy2...這樣的,那么這樣就不是很靈活了呢,動態(tài)代理就能實現(xiàn)。
今天我們介紹JDK的動態(tài)代理,其實還有一種動態(tài)代理cglib,在web開發(fā)中用的比較多,所以就不展開講述了,JDK中已經為我們提提供好了動態(tài)代理接口 InvocationHandler 我們只需要實現(xiàn)它即可創(chuàng)建一個動態(tài)代理類。如下:
/**
* Created by jiangcheng on 2017/11/19.
* 動態(tài)代理
*/
public class DynamicProxy implements InvocationHandler {
private Object mObject;
public DynamicProxy(Object object) {
mObject = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(" DynamicProxy is called");
return method.invoke(mObject, args);
}
/**
* 對外提供一個創(chuàng)建動態(tài)代理對象的方法
* @param object
* @return
*/
public static Object newProxyInstance(Object object) {
return Proxy.newProxyInstance(object.getClass().getClassLoader(),
object.getClass().getInterfaces(), new DynamicProxy(object));
}
}
調用:
public static void main(String args[]) {
// Subject sub = new SubjectProxy(new RealSubject());
// sub.doSomeThing();
// 這里利用的是強轉(動態(tài)創(chuàng)建),所以當有RealSubject2、RealSubject3對象需要代理時,只需要創(chuàng)建一個代理類就行了
Subject subject = (Subject) DynamicProxy.newProxyInstance(new RealSubject());
subject.doSomeThing();
}
結果:

好了,靜態(tài)代理和動態(tài)代理的基本使用和例子都寫完了,但是InvocationHandler的invoke方法是由誰來調用的,代理對象是怎么生成的。invoke()方法中的一些參數(shù)的是什么呢,這就得等到下一part來講述了。