24設計模式之:代理模式

JDK動態代理

       1:jdk動態代理是指在運行時動態的創建被代理類的接口的子類。

       2:再通過反射調用被代理的類方法。

       3:jdk動態代理可以在用戶沒有感覺的情況下,滲入到被代理的方法去執行。(Spring中的AOP思想)

       4:只對一個方法不攔截,getClass()

要求:

       1:jdk動態代理中所有的被代理的類,都必須要擁有一個接口。沒有接口的類,無法被動態代理。


除了jdk代理還有cglib代理,cglib不需要接口就可以實現動態代理,這兩種在Spring中都可以

      

 

以下是一個最基本的JDK動態代理示例:

 在JDK中一個類:有兩個核心類:

       1:Proxy – 用於在運行時創建被代理類的接口的子類。

       2:InvocationHandler – 在執行時攔截被代理類的方法。 執行句柄。


第一步:

/**
 * 聲明一個接口
 * @author zfx
 */
public interface IPerson {
	String run();
}

第二步:

/**
 * 被代理類
 */
public class Person implements IPerson {
	public String run(){
		System.err.println("正在跑步.....");
		return "run....";
	}
}

第三步:

	@Test
	public void test2(){
		//1:聲明被代理類
		final Person p = new Person();
		System.err.println("1:聲明被代理類:"+p+",類名是:"+p.getClass());
		//2:通過Proxy類的靜態方法,在內存中動態的創建IPerson接口的子類
		Object proxyObj = Proxy
						.newProxyInstance(TestUserProxy.class.getClassLoader(),
								  new Class[]{IPerson.class},
								  new InvocationHandler() {//匿名內部類
									public Object invoke(Object proxy, Method method, Object[] args)
											throws Throwable {
										//3:輸出用戶正在調用的方法
										System.err
												.println("4:正在調用的方法名爲:"+method.getName());
										//4:執行目標類的方法,接收返回值
										Object returnValue = method.invoke(p,args);
										System.err
												.println("6:目標方法調用完成,返回值是:"+returnValue);
										return returnValue;
									}
								});
		System.err.println("2:創建了被代理類它是:"+proxyObj.getClass());
		//5:將proxyobj轉成Iperson接口
		IPerson p3 = (IPerson) proxyObj;
		System.err.println("3:轉換成功,開始調用");
		//6:調用了代理類的run方法
		String str = p3.run();
		System.err.println("7:調用完成>");
	}

Junit執行結果:

1:聲明被代理類:cn.zfx.demo4.proxy.Person@276baafc,類名是:class cn.zfx.demo4.proxy.Person
2:創建了被代理類它是:class com.sun.proxy.$Proxy4
3:轉換成功,開始調用
4:正在調用的方法名爲:run
正在跑步.....
6:目標方法調用完成,返回值是:run....
7:調用完成>

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