Java代理(JDK動態代理)

對於靜態代理,如果接口發生改變,那麼代理類和原始對象都要發生改變。而且每一個原始對象都需要一個代理類完成代理操作。因此類數目會相當多。

因此使用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("刪除操作");
	}

}


3、代理對象:

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方法即可。而這種實現也可以看出Spring AOP的實現雛形。完成前後增強。

但是限制還是在於獲得代理類必須依賴於接口。


更加深入的分析有關如何生成代理對象,代理對象如何代用invoke方法,本人還未深究。如果有感興趣者可以查看源碼或者參考以下文章:

http://rejoy.iteye.com/blog/1627405


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章