您好,登錄后才能下訂單哦!
前面做了一個Waiter的動態(tài)代理的練習,這篇繼續(xù)來寫一個練習,一個動態(tài)代理工廠的例子,這個例子在以后學習Spring的時候會有幫助。這個動態(tài)工廠的主要作用就是包裝了下目標對象和前置增強和后置增強。
工廠類的使用步驟
我們要設計一個動態(tài)代理工廠類,以下是使用這個工程類的步驟。
來源:凱哥Java(kaigejava)
1.?創(chuàng)建代理工廠
2.?給工廠設置三樣東西
1)?目標對象,調(diào)用方法setTargetObject()
2)?前置增強,調(diào)用setBeforeAdvice(該接口的具體實現(xiàn))
3)?后置增強,調(diào)用setAfterAdvice(該接口的具體實現(xiàn))
3.?調(diào)用createProxy方法得到代理對象
執(zhí)行代理對象方法時,按照以下順序執(zhí)行。
1)?執(zhí)行BeforeAdvice的before方法
2)?執(zhí)行目標對象的目標方法
3)?執(zhí)行AfterAdvice的after方法
前提準備
新建一個包,把前面的Waiter.java 和ManWaiter.java拷貝過來。
創(chuàng)建動態(tài)代理工廠類
這里我們的代理工廠類,先給出目標對象,前置增強和后置增強,然后創(chuàng)建set和get方法。
下面是前置增強接口代碼
package?demo1;
/**
*?????前置增強??
*?@author?anthony
*
*/
public?interface?BeforeAdvice?{
????
????public?void?before();
}
下面是后置增強接口代碼
package?demo1;
/**
*????后置增強
*?@author?anthony
*
*/
public?interface?AfterAdvice?{
????public?void?after();
}
這里面,我們暫時不知道程序員會在前置增強和后置增強寫什么具體代碼,所以這里我們利用接口來實現(xiàn),程序員到時候?qū)懘a的時候,前置增強必須要實現(xiàn)前置增強接口中的before方法,后置增強必須實現(xiàn)后置增強接口中的after方法。
下面是代理工廠類的代碼
package?demo1;
/**
*?????這個類用來生成代理對象
*?????需要所有參數(shù)
*?????*目標對象
*?????*增強
*?@author?anthony
*
*/
public?class?ProxyFactory?{
????
????private?Object?targetObject;?//?目標對象
????private?BeforeAdvice?beforeAdvice;?//?前置增強
????private?AfterAdvice?afterAdvice;?//?后置增強
????
????
????public?Object?getTargetObject() {
????????return?targetObject;
????}
????public?void?setTargetObject(Object?targetObject) {
????????this.targetObject?=?targetObject;
????}
????public?BeforeAdvice?getBeforeAdvice() {
????????return?beforeAdvice;
????}
????public?void?setBeforeAdvice(BeforeAdvice?beforeAdvice) {
????????this.beforeAdvice?=?beforeAdvice;
????}
????public?AfterAdvice?getAfterAdvice() {
????????return?afterAdvice;
????}
????public?void?setAfterAdvice(AfterAdvice?afterAdvice) {
????????this.afterAdvice?=?afterAdvice;
????}
}
這里三個對象都給生成set和get方法,方便調(diào)用。
創(chuàng)建代理對象
前面代碼都不是重點,我們代理工廠重點部分來了,就是如何創(chuàng)建代理對象。這部分是在工廠類中,實現(xiàn)createProxy()方法,是本篇的重點內(nèi)容,代碼如下。
package?demo1;
import?java.lang.reflect.InvocationHandler;
import?java.lang.reflect.Method;
import?java.lang.reflect.Proxy;
import?org.omg.CORBA.portable.InvokeHandler;
/**
*?????這個類用來生成代理對象
*?????需要所有參數(shù)
*?????*目標對象
*?????*增強
*?@author?anthony
*
*/
public?class?ProxyFactory?{
????
????private?Object?targetObject;?//?目標對象
????private?BeforeAdvice?beforeAdvice;?//?前置增強
????private?AfterAdvice?afterAdvice;?//?后置增強
????
????/**
?????*????生成代理對象
?????*?@return
?????*/
????public?Object?createProxy() {
????????// 1.?給出三大參數(shù)
????????ClassLoader?loader?=?this.getClass().getClassLoader();
????????Class[]?interfaces?=?targetObject.getClass().getInterfaces();
????????InvocationHandler?h?=?new?InvocationHandler() {
????????????public?Object?invoke(Object?proxy, Method?method, Object[]?args)?throws?Throwable {
????????????????//?執(zhí)行前置增強
????????????????if(beforeAdvice?!=?null) {
????????????????????beforeAdvice.before();
????????????????}
????????????????//?執(zhí)行目標對象目標方法
????????????????Object?result?=?method.invoke(targetObject,?args);
????????????????//?執(zhí)行后置增強
????????????????if(afterAdvice?!=?null) {
????????????????????afterAdvice.after();
????????????????}
????????????????return?result;
????????????}
????????};
????????
????????// 2.?得到代理對象
????????Object?proxyObject?=?Proxy.newProxyInstance(loader,?interfaces,?h);
????????return?proxyObject;
????}
????
????public?Object?getTargetObject() {
????????return?targetObject;
????}
????public?void?setTargetObject(Object?targetObject) {
????????this.targetObject?=?targetObject;
????}
????public?BeforeAdvice?getBeforeAdvice() {
????????return?beforeAdvice;
????}
????public?void?setBeforeAdvice(BeforeAdvice?beforeAdvice) {
????????this.beforeAdvice?=?beforeAdvice;
????}
????public?AfterAdvice?getAfterAdvice() {
????????return?afterAdvice;
????}
????public?void?setAfterAdvice(AfterAdvice?afterAdvice) {
????????this.afterAdvice?=?afterAdvice;
????}
}
上面代碼就是在createProxy()方法的時候,把目標對象和增強給做了以下組裝。接下來,看看如何代碼使用這個工廠類。
測試工廠類的使用
新建一個Demo1.java文件,寫代碼來使用ProxyFactory這個動態(tài)代理工廠類。
package?demo1;
import?org.junit.Test;
public?class?Demo1 {
????
????@Test
????public?void?fun1() {
????????// 1.?創(chuàng)建工廠類對象
????????ProxyFactory?factory?=?new?ProxyFactory();
????????//?2.設置目標對象
????????factory.setTargetObject(new?ManWaiter());
????????//?3.設置前置增強
????????factory.setBeforeAdvice(new?BeforeAdvice() {
????????????public?void?before() {
????????????????System.out.println("你好,歡迎光臨!");
????????????}
????????});
????????//?4.設置后置增強
????????factory.setAfterAdvice(new?AfterAdvice() {
????????????public?void?after() {
????????????????System.out.println("再見,歡迎下次再來!");
????????????}
????????});
????????
????????// 5.?獲取代理對象,?執(zhí)行增強代碼
????????Waiter?waiter?= (Waiter)factory.createProxy();
????????waiter.serve();
????}
}
運行單元測試,得到如下輸出。
聯(lián)系凱哥:凱哥Java(kaigejava)
凱哥個人博客:www.kaigejava.com
個人博客上可以發(fā)即時消息給凱哥哦~
你好,歡迎光臨!
服務中...
再見,歡迎下次再來!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。