前面作了一個Waiter的動態代理的練習,這篇繼續來寫一個練習,一個動態代理工廠的例子,這個例子在之後學習Spring的時候會有幫助。這個動態工廠的主要做用就是包裝了下目標對象和前置加強和後置加強。
java
工廠類的使用步驟程序員
咱們要設計一個動態代理工廠類,如下是使用這個工程類的步驟。ide
來源:凱哥Java(kaigejava)單元測試
1. 建立代理工廠學習
2. 給工廠設置三樣東西測試
1) 目標對象,調用方法setTargetObject()this
2) 前置加強,調用setBeforeAdvice(該接口的具體實現)spa
3) 後置加強,調用setAfterAdvice(該接口的具體實現)設計
3. 調用createProxy方法獲得代理對象代理
執行代理對象方法時,按照如下順序執行。
1) 執行BeforeAdvice的before方法
2) 執行目標對象的目標方法
3) 執行AfterAdvice的after方法
前提準備
新建一個包,把前面的Waiter.java 和ManWaiter.java拷貝過來。
建立動態代理工廠類
這裏咱們的代理工廠類,先給出目標對象,前置加強和後置加強,而後建立set和get方法。
下面是前置加強接口代碼
package demo1;
/**
* 前置加強
* @author anthony
*
*/
public interface BeforeAdvice {
public void before();
}
下面是後置加強接口代碼
package demo1;
/**
* 後置加強
* @author anthony
*
*/
public interface AfterAdvice {
public void after();
}
這裏面,咱們暫時不知道程序員會在前置加強和後置加強寫什麼具體代碼,因此這裏咱們利用接口來實現,程序員到時候寫代碼的時候,前置加強必需要實現前置加強接口中的before方法,後置加強必須實現後置加強接口中的after方法。
下面是代理工廠類的代碼
package demo1;
/**
* 這個類用來生成代理對象
* 須要全部參數
* *目標對象
* *加強
* @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方法,方便調用。
建立代理對象
前面代碼都不是重點,咱們代理工廠重點部分來了,就是如何建立代理對象。這部分是在工廠類中,實現createProxy()方法,是本篇的重點內容,代碼以下。
package demo1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.omg.CORBA.portable.InvokeHandler;
/**
* 這個類用來生成代理對象
* 須要全部參數
* *目標對象
* *加強
* @author anthony
*
*/
public class ProxyFactory {
private Object targetObject; // 目標對象
private BeforeAdvice beforeAdvice; // 前置加強
private AfterAdvice afterAdvice; // 後置加強
/**
* 生成代理對象
* @return
*/
public Object createProxy() {
// 1. 給出三大參數
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 {
// 執行前置加強
if(beforeAdvice != null) {
beforeAdvice.before();
}
// 執行目標對象目標方法
Object result = method.invoke(targetObject, args);
// 執行後置加強
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這個動態代理工廠類。
package demo1;
import org.junit.Test;
public class Demo1 {
@Test
public void fun1() {
// 1. 建立工廠類對象
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. 獲取代理對象, 執行加強代碼
Waiter waiter = (Waiter)factory.createProxy();
waiter.serve();
}
}
運行單元測試,獲得以下輸出。
聯繫凱哥:凱哥Java(kaigejava)
凱哥我的博客:www.kaigejava.com
我的博客上能夠發即時消息給凱哥哦~
你好,歡迎光臨!
服務中...
再見,歡迎下次再來!