一種代理方式是代理已經實現了接口的類,jdkProxy;
jdkProxy是Java類庫中自帶的類;創建代理對象的方式:
實現代理需要基於Proxy類和InvocationHandler接口,使用Proxy類中的newProxyInstance()方法來完成創建,同時在該方法中直接創建實現InvocationHandler接口的匿名內部類對象,並實現invoke方法在該方法中進行方法的增強。
final IProduce producer=new Produce(); /*注意這里通過Proxy類中的靜態方法newProxyInstance來創建對象,注意其中需要創建接口InvocationHandler的匿名對象來進行方法增強*/ IProduce jdkProduce=(IProduce) Proxy.newProxyInstance(producer.getClass().getClassLoader(),producer.getClass().getInterfaces(), new InvocationHandler(){ @Override /*在這里進行所需要的方法增強實現*/ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object ret=null; Float money=(Float)args[0]; if("Service".equals(method.getName())){ args[0]=money*1.6f; ret=method.invoke(producer,args);//money+money*0.6f); } if("AfterService".equals(method.getName())){ //注意這個1.5默認是double類型的,所以需要在尾端加上f,標注出來 args[0]=money*1.5f; //注意這里映射到對象的方法中,並帶入參數 ret=method.invoke(producer, args); } // TODO Auto-generated method stub return ret; } });
另一種代理方式能代理未實現接口的類,但不能代理final修飾的終止類,cglib;
cglib需要從外部導入jar包才能使用;實現代理需要基於Enhancer類,並使用該類中的create方法來創建;在該方法中創建實現MethodInterceptor接口的匿名內部類對象,並在intercept方法,在該方法中編寫方法增強模塊。
final Produce producer=new Produce(); Produce cglibProduce=(Produce) Enhancer.create(producer.getClass(), producer.getClass().getInterfaces(),new MethodInterceptor() { @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { // 在這里對具體方法實現加強 return null; } });
歸納總結發現兩種動態代理的方式其實在整體框架上非常相似,但是顯然cglib創建代理的適應面更廣,在Spring的AOP中,是通過cglib來創建動態代理的。