Java動態代理的簡單學習

如果把要被代理的對象比喻成演員,那代理對象就是它的經紀人。

經紀人會幫助演員處理很多事情,體現在代碼裏就是各種各樣的方法。

所以說代理對象方便了被代理對象的日後維護和修改,降低了程序的耦合性,提高了程序的魯棒性。

功能介紹完了,我們來看一下具體的實例:

要實現動態代理,要實現兩個重要的類,一個是Proxy——生成代理對象的類,一個是 InvocationHandler——處理被代理對象的類,可以進行自定義。

首先來看一下實現動態代理的格式:

Proxy.newProxyInstance(loader, interfaces, h);

Proxy——用來生成代理對象

newProxyInstance(...)——創建一個Proxy實例

loader——當前類的類加載器

interfaces——被代理對象的所有接口

h——InvocationHandler處理類的實現

從格式上可以看出來,實現動態代理要獲取當前類的類加載器,在哪個類中就獲取哪個類的加載器即可,還要獲取被代理對象的所有接口。

下面通過實例來看一下動態代理的用法:

package cn.itcast_動態代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

public class Demo {
	
	public static void main(String[] args) {
		
		//list是被代理的對象
		final ArrayList list = new ArrayList();
		
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		System.out.println(list);
		
		ArrayList list2 = new ArrayList();
		list.add("xx");
		
		List p = (List)Proxy.newProxyInstance(Demo.class.getClassLoader(), list.getClass().getInterfaces(), 
				
				new InvocationHandler() {
					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						//System.out.println(proxy.getClass());
						
						//增強add方法
						String name = method.getName();
						//System.out.println(name);
						if("add".equals(name))
						{
							System.out.println("進行添加操作:");
							list.add("***");
							return true;
						}
						
						if("size".equals(name))
						{
							return 0;
						}
						
						if("remove".equals(name))
						{
							throw new UnsupportedOperationException();
						}
						return method.invoke(list, args);
					}
				});
		//代理對象p中與add方法名相同的方法,並非list中原來的add方法,所以結果會返回false
		boolean b = p.add("123");
		System.out.println("添加成功?"+b);
		
		//同理此size方法也是p中的與size同名的方法
		int n = p.size();
		System.out.println("該集合中一共有:"+n+"個元素");
		
		//輸出list後,發現list中並非沒有元素,而是有四個元素
		System.out.println(list);
		//addAll方法因爲沒有在p中進行判斷,所以沒有影響
		p.addAll(list2);
		
		//這裏也是p中經過判斷的remove方法
		boolean re = p.remove("aaa");
		System.out.println("移除成功?"+re);
	}

}

此處我們把創建的list對象當做被代理對象,按照上面的格式創建Proxy實例後,在InvocationHandler處理類中重寫invoke方法,獲取list對象的方法名後list對象中的方法就任我們擺佈了,在進行判斷並對list中的add、size、remove方法進行操作後,我們試着調用一下p對象的add、size和remove方法,控制檯會出現這樣的結果:

其中,add、size、remove方法的都是按照p對象中判斷後的同名方法執行的,而沒有進行判斷的靜態方法addAll還是按照list對象中的原來的功能執行,由此可見,動態代理可以修改被代理對象中的方法,從而降低了程序的耦合性,提高了程序的可維護性。

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