cglib动态代理实现

来源:互联网 发布:java中如何记录日志 编辑:程序博客网 时间:2024/06/05 05:21

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()方法,最终执行的都是目标类的方法,所以只会进行一次.

那么就要想办法可以循环执行,介于需要执行上一次代理子类的方法,那么我们将这个上级代理子类传递进来.每次多级代理的时候进行父级目标类的设入,达到多次增强的效果.

原创粉丝点击