舉個例子:假如有一個殺手專殺男的,不殺女的。代碼如下:
public interface Killer {void kill(String name, String sex);void watch(String name);
}public class ManKiller implements Killer {@Overridepublic void kill(String name, String sex) {if (sex.equals("man")) {System.out.println(name + "已被擊殺!");} else {System.out.println(name + "為女性,不殺之!");}}@Overridepublic void watch(String name) {System.out.println(name + "已被監視!");}
}
但是有一個老板雇傭他殺了馬冬梅(女),也就是kill("馬冬梅", "women");要執行擊殺命令!要怎么實現?
可以在擊殺之前,原則上把馬冬梅當做男的處理,就可以執行擊殺命令了!代碼如下:
public class KillerPrinciple implements InvocationHandler {private Object object;public KillerPrinciple(Object object) {this.object = object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {boolean isReward = false;String methodName = method.getName();if(methodName.equals("kill")){boolean isSpecailWomen = false;for (int i = 0; i < args.length; i++) {if(args[i].equals("馬冬梅")){isSpecailWomen = true;//馬冬梅是特殊女性}}if(isSpecailWomen){for (int i = 0; i < args.length; i++) {if(args[i].equals("women")){args[i] = "man";//直接當做男性處理isReward = true;}}}}//通過java反射機制調用目標代碼method.invoke(object, args);if(isReward){System.out.println("老板獎勵殺手5000萬美金!");}return null;}
}
然后把這個原則告訴這個殺手就可以完成老板交代的任務了!代碼如下:
public static void main(String[] args) {ManKiller manKiller = new ManKiller();Killer principledKiller = toPrincipledKiller(manKiller);principledKiller.kill("小明", "man");principledKiller.kill("小紅", "women");principledKiller.watch("馬冬梅");principledKiller.kill("馬冬梅", "women");
}
private static Killer toPrincipledKiller(ManKiller manKiller) {ClassLoader classLoader = manKiller.getClass().getClassLoader();Class<?>[] interfaces = manKiller.getClass().getInterfaces();KillerPrinciple killerPrinciple = new KillerPrinciple(manKiller);Killer proxy = (Killer) Proxy.newProxyInstance(classLoader, interfaces, killerPrinciple);return proxy;}
輸出結果:
小明已被擊殺!
小紅為女性,不殺之!
馬冬梅已被監視!
馬冬梅已被擊殺!
老板獎勵殺手5000萬美金!
所以,使用動態代理是為了在不改變目標對象代碼的前提下,在目標代碼執行前后,可以根據目標方法和參數執行相應的邏輯,以及可以過濾和改變參數的信息。