關於Java動態代理
阿新 • • 發佈:2021-01-11
思想,在不改變原有程式碼的基礎上,對方法進行增強
其實現方式有兩種:
一、基於介面的動態代理
對應的引數介紹:actor.getClass().getClassLoader()表示類載入器,和被代理物件使用相同的類載入器,固定寫法
actor.getClass().getInterfaces()表示被代理物件實現的介面,要求被代理物件和代理物件具有相同的行為,固定寫法
InvocationHandler表示要增強的程式碼,執行任何被代理物件的任何方法都經過此方法,該方法有攔截作用
1 IActor proxyActor = (IActor) Proxy.newProxyInstance(actor.getClass().getClassLoader(),View Code2 actor.getClass().getInterfaces(), new InvocationHandler() { 3 4 @Override 5 public Object invoke(Object proxy, Method method, Object[] args) 6 throws Throwable { 7 8 Object rtValue = null; 9 //1、取出執行方法中的引數 10 Float money = (Float) args[0]; 11 //2、判斷當前執行的是什麼方法 12 if("basicAct".equals(method.getName())){13 //基本演出 14 if(money > 10000){ 15 //執行方法開始表演 16 rtValue = method.invoke(actor, money); 17 } 18 } 19 if("dengerAct".equals(method.getName())){ 20 //基本演出 21 if(money > 50000){ 22 //執行方法開始表演 23 rtValue = method.invoke(actor, money); 24 } 25 } 26 return rtValue; 27 } 28 });
二、基於子類的動態代理
需要提供CGLIB的包,要求:被代理類不能是最終類,不能被final修飾
Actor cglibActor = (Actor) Enhancer.create (actor.getClass(), new MethodInterceptor() { /** * 引數介紹: * proxy:表示代理物件的引用 * method:當前執行的方法 * arg0:當前執行方法的引數 */ @Override public Object intercept(Object proxy, Method method, Object[] arg0, MethodProxy arg3) throws Throwable { Object rtValue = null; Float money = (Float) arg0[0]; if("basicAct".equals(method.getName())){ //動態代理新增的條件,演員演出時,經紀公司出面 if(money > 10000){ //開始呼叫方法,actor為建立物件的引用,money為該方法的引數 rtValue = method.invoke(actor, money/2); } } if("dengerAct".equals(method.getName())){ if(money > 50000){ rtValue = method.invoke(actor, money/2); } } return rtValue; } });