對於靜態代理,如果接口發生改變,那麼代理類和原始對象都要發生改變。而且每一個原始對象都需要一個代理類完成代理操作。因此類數目會相當多。
因此使用jdk動態代理時,動態代理類始終只有一個invoke方法,當接口發生改變時,動態代理的接口不用隨之改變。但是要求目標對象必須實現接口,因爲它創建代理對象的時候是根據接口創建的。如果不實現接口,jdk無法給目標對象創建代理對象。
動態代理現在只能代理接口,實現是依靠Java反射機制和動態生成class技術。而Spring的AOP也就是應用到jdk動態代理技術。
實例如下:依舊使用保護代理模擬權限控制
1、接口:
/**
* 由於使用jdk動態代理,必須依賴於實現接口
* @author cai.wuxin
*
*/
public interface OAOperate {
public void add();
public void select();
public void delete();
}
2、目標對象:
public class OAOperateImpl implements OAOperate{
private String name;
private int flag;
public OAOperateImpl(String name,int flag) {
this.name = name;
this.flag = flag;
}
public int getFlag(){
return this.flag;
}
@Override
public void add() {
//省略相應操作
}
@Override
public void select() {
//省略相應操作
}
/**
* delete需要權限設置
*/
@Override
public void delete() {
//省略相應操作
System.out.println("刪除操作");
}
}
public class DynamicProxy implements InvocationHandler{
private OAOperateImpl operate = null;
public OAOperate getProxyInterface(OAOperateImpl operate){
this.operate = operate;
OAOperate oApi = (OAOperate)Proxy.newProxyInstance(
operate.getClass().getClassLoader(),
operate.getClass().getInterfaces(),
this);
return oApi;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
if(method.getName().startsWith("delete")){
if(operate.getFlag()==4){
return method.invoke(operate, args);
}else{
System.out.println("權限不足");
}
}else{
return method.invoke(operate, args);
}
return null;
}
}
4、客戶端實現:
public class Client {
public static void main(String []args){
OAOperateImpl o1 = new OAOperateImpl("lilei",3);
OAOperateImpl o2 = new OAOperateImpl("hanmeimei",4);
DynamicProxy dp1 = new DynamicProxy();
DynamicProxy dp2 = new DynamicProxy();
OAOperate proxy1 = dp1.getProxyInterface(o1);
OAOperate proxy2 = dp2.getProxyInterface(o2);
proxy1.delete();
proxy2.delete();
}
}
5、運行結果:
權限不足
刪除操作
但是限制還是在於獲得代理類必須依賴於接口。
更加深入的分析有關如何生成代理對象,代理對象如何代用invoke方法,本人還未深究。如果有感興趣者可以查看源碼或者參考以下文章:
http://rejoy.iteye.com/blog/1627405