hadoop20---代理另一種方式
阿新 • • 發佈:2018-05-12
loader RR 自己 參數 轉發 oca exception out discount
package cn.itcast_05_proxy.service; /** * 這是一個業務的接口,這個接口中的業務就是返回衣服的價格 */ public interface IBoss {//接口 int yifu(String size); }
package cn.itcast_05_proxy.service.impl; import cn.itcast_05_proxy.service.IBoss; /** * 實現了賣衣服的接口 * 自定義了自己的業務,賣褲子 * */ public class Boss implements IBoss{ public intyifu(String size){ //接口的方法 System.err.println("天貓小強旗艦店,老板給客戶發快遞----衣服型號:"+size); //這件衣服的價錢,從數據庫讀取 return 50; } public void kuzi(){ //不是接口的方法 System.err.println("天貓小強旗艦店,老板給客戶發快遞----褲子"); } }
不用代理實現:
package cn.itcast_05_proxy.action; import org.junit.Test; importcn.itcast_05_proxy.service.IBoss; import cn.itcast_05_proxy.service.impl.Boss; public class SaleAction { /** * 不使用代理,直接調用方法 * 方法中規定什麽業務,就只能調用什麽業務,規定什麽返回值,就只能輸出什麽返回值 */ @Test public void saleByBossSelf() throws Exception { IBoss boss = new Boss(); System.out.println("老板自營!"); int money = boss.yifu("xxl");// 老板自己賣衣服,不需要客服,結果就是沒有聊天記錄 System.out.println("衣服成交價:" + money); } }
用代理實現:
package cn.itcast_05_proxy.proxyclass; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import cn.itcast_05_proxy.service.IBoss; import cn.itcast_05_proxy.service.impl.Boss; public class ProxyBoss { /** 擴展方法的實現不是加方法。 IBoss boss = ProxyBoss.getProxy(10,IBoss.class,Boss.class), boss就是代理類的實例, int money = boss.yifu("xxl"); */ public static <T> T getProxy(final int discountCoupon,final Class<?> interfaceClass, final Class<?> implementsClass) throws Exception { //這裏傳的參數類型跟hadoop--19的類型不一樣 return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(),new Class[] { interfaceClass }, new InvocationHandler() { public Object invoke(Object proxy, Method method,Object[] args) throws Throwable { Integer returnValue = (Integer) method.invoke(implementsClass.newInstance(), args); // 調用原始對象以後返回的值 return returnValue - discountCoupon; } }); } } /* 當我們通過代理對象調用一個方法的時候,這個方法的調用就會被轉發為由InvocationHandler這個接口的 invoke 方法來進行調用。 Object invoke(Object proxy, Method method, Object[] args) throws Throwable proxy: 指代我們所代理的那個真實對象 method: 指代的是我們所要調用真實對象的某個方法的Method對象 args: 指代的是調用真實對象某個方法時接受的參數 Proxy這個類的作用就是用來動態創建一個代理對象的類,它提供了許多的方法,但是我們用的最多的就是 newProxyInstance 這個方法, 這個方法的作用就是得到一個動態的代理對象, public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException loader: 一個ClassLoader對象,定義了由哪個ClassLoader對象來對生成的代理對象進行加載 interfaces: 一個Interface對象的數組,表示的是我將要給我需要代理的對象提供一組什麽接口,如果我提供了一組接口給它,那麽這個代理對象就宣稱實現了該接口(多態),這樣我就能調用這組接口中的方法了 h: 一個InvocationHandler對象,表示的是當我這個動態代理對象在調用方法的時候,會關聯到哪一個InvocationHandler對象上 */
package cn.itcast_05_proxy.action; import org.junit.Test; import cn.itcast_05_proxy.proxyclass.ProxyBoss; import cn.itcast_05_proxy.service.IBoss; import cn.itcast_05_proxy.service.impl.Boss; /** * 什麽是動態代理? 簡單的寫一個模板接口,剩下的個性化工作,好給動態代理來完成! */ public class ProxySaleAction { /** *使用代理,在這個代理中,只代理了Boss的yifu方法 *定制化業務,可以改變原接口的參數、返回值等 */ @Test public void saleByProxy() throws Exception { IBoss boss = ProxyBoss.getProxy(10,IBoss.class,Boss.class);// 將代理的方法實例化成接口 //IBoss boss = new Boss();// 將代理的方法實例化成接口 System.out.println("代理經營!"); int money = boss.yifu("xxl");// 調用接口的方法,實際上調用方式沒有變 System.out.println("衣服成交價:" + money); } }
hadoop20---代理另一種方式