cglib動態代理實現
cglib實現apo功能
實現
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
//目標類 public class Subject { public int a=0; public Map<String,String> map=new HashMap<String,String>(); public int say(String name){ a++; System.out.println("say:"+name+"--"+a); return name.length(); } public void putMap(String key,String value){ map.put(key,value); } public String getMap(){ return map.toString(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
//代理類 public class CglibProxyOne implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { // 排除Object類中的toString等方法 //(和jdk代理一樣都會把Object的toString,equals,hashCode方法進行代理)這邊進行過濾 boolean objFlag = method.getDeclaringClass().getName().equals("java.lang.Object"); if(!objFlag){ System.out.println("before"); } //通過代理類調用父類中的方法 Object result = methodProxy.invokeSuper(o, args); if(!objFlag){ System.out.println("after"); } return result; } }
|
1 2 3 4 5 6 7 8 9
|
//測試類 public class Main { public static void main(String[] args) { CglibProxyMore proxy=new CglibProxyMore(); Subject proxyImpl=(Subject)Enhancer.create(Subject.class,proxy); proxy.setTargetObj(proxyImpl); proxyImpl.say("cff"); } }
|
1 2 3 4
|
輸出: before say:test--1 after
|
cglib是可以直接以class進行代理,這邊實現了單次的增強,重點是CglibProxyOne類中進行了方法增強.那麼想要多次增強該怎麼辦呢?
cglib進行多次增強
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
public class CglibProxyMore implements MethodInterceptor { private Object targetObj; public void setTargetObj(Object targetObj) { this.targetObj = targetObj; } @Override public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { // 排除Object類中的toString等方法 boolean objFlag = method.getDeclaringClass().getName().equals("java.lang.Object"); if(!objFlag){ System.out.println("before"); } //通過代理類調用父類中的方法 Object result = methodProxy.invokeSuper(targetObj, args); if(!objFlag){ System.out.println("after"); } return result; } }
|
思考: 代理類進行多次代理,進行測試
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
public class Main2 { public static void main(String[] args) { CglibProxyMore proxy=new CglibProxyMore(); Enhancer e = new Enhancer(); e.setSuperclass(Subject.class); e.setCallback(proxy); Subject proxyImpl= (Subject) e.create(); proxy.setTargetObj(new Subject()); //---------- CglibProxyMore proxy2=new CglibProxyMore(); Enhancer e2 = new Enhancer(); e2.setSuperclass(Subject.class); e2.setCallback(proxy2); proxy2.setTargetObj(proxyImpl); Subject proxyImpl2= (Subject) e2.create(); proxyImpl2.say("asdas"); } }
|
1 2 3 4
|
輸出: before say:asdas--1 after
|
還是隻有一次,然後發現methodProxy代理對象執行的是invokerSuper方法,只會執行一次目標類的方法,所以只會進行一次增強.
那麼改成invoke;
1
|
Object result = methodProxy.invoke(targetObj, args);
|
1 2 3 4 5 6
|
輸出: before before say:asdas--1 after after
|
因爲cglib動態代理針對類進行代理,對指定的類生成一個代理子類,那麼想要多次增強,是否可以對代理子類再次進行代理,如果是這樣,依舊用invokeSuper()方法,最終執行的都是目標類的方法,所以只會進行一次.
那麼就要想辦法可以循環執行,介於需要執行上一次代理子類的方法,那麼我們將這個上級代理子類傳遞進來.每次多級代理的時候進行父級目標類的設入,達到多次增強的效果.