概述 : Spring 框架有一個技術, 叫做 AOP 技術. (面向切面編程)
效果 : 攔截被調用對象的所有方法.
實現類完成
接口定義 :
public interface SuperStar {
void sing(int money);
void liveShow(int money);
void sleep();
}
實現類定義 :
public class LiuYan implements SuperStar {
@Override
public void sing(int money) {
System.out.println("柳巖爲了唱了一首 <真的真的很愛你!> 歌曲. 掙了 = " + money);
}
@Override
public void liveShow(int money) {
System.out.println("柳巖參加了 <屌絲男士!> 節目. 掙了 = " + money);
}
@Override
public void sleep() {
System.out.println("柳巖真的很累了, 休息休息...");
}
}
測試類定義 :
@Test
public void test1() {
SuperStar star = new LiuYan();
star.sing(-10);
star.liveShow(-20);
star.sleep();
}
@Test
public void test2() {
SuperStar star = new LiuYan();
/************ 動態代理對象 start **************/
// 1. 使用 Proxy 類調用 newProxyInstance 方法
// 1.1 類加載器 (與被代理對象保持一致)
ClassLoader loader = star.getClass().getClassLoader();
// 1.2 interfaces 接口行爲規範 (與被代理對象保持一致)
Class<?>[] interfaces = star.getClass().getInterfaces();
// 1.3 InvocationHandler 調用處理器 (實現類)
// 注意點 : 返回的 Object 類型對象必須要轉成接口實現.
SuperStar proxy = (SuperStar) Proxy.newProxyInstance(loader, interfaces, new MyInvocationHandler(star));
/************ 動態代理對象 end **************/
// System.out.println(proxy.getClass());
proxy.sing(10000);
proxy.liveShow(200000);
proxy.sleep();
}
MyInvocationHandler 實現類代碼編寫 :
簡化版本 :
public class MyInvocationHandler implements InvocationHandler {
// 屬性
private SuperStar star;
// 構造方法
public MyInvocationHandler(SuperStar star) {
this.star = star;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 直接放行
return method.invoke(star, args);
}
}
判斷版本 :
public class MyInvocationHandler implements InvocationHandler {
// 屬性
private SuperStar star;
// 構造方法
public MyInvocationHandler(SuperStar star) {
this.star = star;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 1. 判斷方法
if (method.getName().equals("sing")) {
// 2. 取出參數
int money = (int) args[0];
// 3. 判斷參數
if (money < 10000) {
System.out.println("滾, 你這個窮屌絲, 趕緊回家擼代碼去...");
return null;
}
// 4. 參數合法
// 抽提成
System.out.println("代理抽取了 " + (money * 0.3) + " 回扣.");
// 5. 調用真實的方法
return method.invoke(star, (int)(money * 0.7));
} else if ("liveShow".equals(method.getName())) {
// 2. 取出參數
int money = (int) args[0];
// 3. 判斷參數
if (money < 100000) {
System.out.println("滾, How old are you. 繼續回家擼代碼去...");
return null;
}
// 4. 參數合法
// 抽提成
System.out.println("代理抽取了 " + (money * 0.3) + " 回扣.");
// 5. 調用真實的方法
return method.invoke(star, (int)(money * 0.7));
}
return method.invoke(star, args); // 其它方法直接放行 (close 池)
}
}