cglib实现动态代理简单使用

Boss:

package proxy.cglib;


public class Boss{
    public void findPerson() {
        System.out.println("我要找java架构师");
    }
}

WebApp:

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 方法拦截器
 * CGLib 代理的目标对象不需要实现任何接口,它是通过动态继承目标对象 实现的动态代理
 */
public class WebApp implements MethodInterceptor {
    public Object getInstance(Class<?> clazz){
        Enhancer enhancer = new Enhancer();
        //告诉cglib,生成的子类需要继承哪个类
        enhancer.setSuperclass(clazz);
        //设置回调
        enhancer.setCallback(this);
        //生成源代码
        //编译成class文件
        //加载到JVM中,并返回被代理对象
        return enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //这个obj的引用是由CGLib给我们new出来的
        //cglib new出来以后的对象,是被代理对象的子类
        //在new子类之前,实际上默认先调用了我们super()方法的,
        //new子类的同时,必须先new出来父类,这就相当于是间接的持有了我们父类的引用
        //子类重写了父类的所有的方法
        //我们改变子类对象的某些属性,是可以间接的操作父类的属性的
        before();
        Object obj = methodProxy.invokeSuper(o, objects);//这里是调父类的(子类死循环)
        after();
        return obj;
    }
    private void after() {
        System.out.println("---------------");
    }

    private void before() {
        System.out.println("找Person,找我WebApp cglib");
        System.out.println("---------------");
    }
}

Test:

package proxy.cglib;

/**
 * JDK的动态代理是通过接口来进行强制转换的
 * 生成以后的代理对象,可以强制转换为接口
 *
 *CGLib的动态代理是通过生成一个被代理对象的子类,然后重写父类的方法
 * 生成以后的对象,可以强制转换为被代理对象
 * 子类引用赋值给父类
 */
public class Test {
    public static void main(String[] args){
        try {
            Boss boss = (Boss) new WebApp().getInstance(Boss.class);
            boss.findPerson();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

将 CGLib 代理 后的 class 写入到磁盘,然后,我们再反编译一探究竟

 

CGLib 和 JDK 动态代理对比
1.JDK 动态代理是实现了被代理对象的接口,CGLib 是继承了被代理对象。

2.JDK 和 CGLib 都是在运行期生成字节码,JDK 是直接写 Class 字节码,CGLib 使用 ASM 框架写 Class 字节码,Cglib 代理实现更复杂,生成代理类比 JDK 效率低。
3.JDK 调用代理方法,是通过反射机制调用,CGLib 是通过 FastClass 机制直接调用方法, CGLib 执行效率更高 

原文地址:https://www.cnblogs.com/fly-book/p/10361846.html