目录
原理实例
cglib代码实例
注意:测试要是发生报异常
cglib是利用生成子类继承父类的方法实现的动态代理
首先构造父类Singer
public class Singer {
public void dance(){
System.out.println("跳舞");
}
public void singing(){
System.out.println("唱歌");
}
}
构造子类继承父类,实现代理
public class SingerSub extends Singer {
@Override
public void dance() {
System.out.println("经纪人商量合同");
super.dance();
System.out.println("收钱");
}
@Override
public void singing() {
System.out.println("经纪人商量合同");
super.singing();
System.out.println("收钱");
}
}
方法执行
public class Main {
public static void main(String[] args) {
Singer singer = new SingerSub();
singer.singing();
singer.dance();
}
}
运行结果
可以看出,我并未用静态代理,也没有用proxy类去实现,就是单纯的继承关系。理解到这就是cglib的原理
首先之前一样建立Singer接口
public interface Singer {
void sing();
void dance();
}
然后实现方法
public class ZStar implements Singer{
@Override
public void sing() {
System.out.println("我会唱歌.......");
}
@Override
public void dance() {
System.out.println("我会跳舞......");
}
}
建立代理规则,这一步和Proxy有很大相似性,只不过是proxy继承的InvocationHandler接口,而cglib继承的是MethodInterceptor,
public class TargetCglib implements MethodInterceptor {
private ZStar zStar;
public TargetCglib(ZStar zStar) {
this.zStar = zStar;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("签合同");
Object invoke = methodProxy.invokeSuper(o, objects);//调用原方法
//Object invoke = method.invoke(zStar, objects);
//Object invoke = methodProxy.invokeSuper(zStar, objects);
System.out.println("收钱");
return invoke;
}
}
其中注释的内容是三种不同的代理执行方法的方法,可以自己试试。
要说明的是
invokeSuper调用的是被代理类的方法, 但只有代理类才存在基类, 必须使用代理类作为obj参数调用
invoke调用的是增强方法, 必须使用被代理类的对象调用, 使用代理类会造成OOM
主方法运行
public class Main {
public static void main(String[] args) {
Enhancer en = new Enhancer();//用来帮我们生成代理对象
en.setSuperclass(ZStar.class);//设置要代理的目标类
en.setCallback(new TargetCglib(new ZStar()));//设置执行规则,相当于proxy的Ruler
ZStar s = (ZStar)en.create();//创造代理对象
s.dance();//方法测试
System.out.println("********************");
s.sing();
}
}
其中Enhancer就是cglib用来帮我们生成代理对象的,再用setSuperclass设定代理的目标类,在设定代理规则,也就是我们上边设定的签合同收钱,create()生成代理对象,测试运行得到结果
Exception in thread "main" java.lang.NoClassDefFoundError: org/objectweb/asm/Type
.................
Caused by: java.lang.ClassNotFoundException: org.objectweb.asm.Type
可以试着换一下cglib的jar包,更换成cglib-full.jar