cglib動態代理實現

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()方法,最終執行的都是目標類的方法,所以只會進行一次.

那麼就要想辦法可以循環執行,介於需要執行上一次代理子類的方法,那麼我們將這個上級代理子類傳遞進來.每次多級代理的時候進行父級目標類的設入,達到多次增強的效果.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章