cglib初步使用代理

业务类:

public class UserServiceImpl {
    public void add() {
        System.out.println("add方法!");
    }
    public final void delete() {//final方法不能被代理,直接输出,不会输出代理中打印语句
        System.out.println("delete方法!");
    }
}

代理类执行的逻辑:

import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class MyMethodInterceptor implements MethodInterceptor  {
    public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
        System.out.println("before:"+ method);

        Object resultInfo = proxy.invokeSuper(obj, arg);

        System.out.println("after:"+ method);
        return resultInfo;
    }
}

测试:

public class CglibProxyTest {
//  使用cglib[Code Generation Library]实现动态代理,并不要求委托类必须实现接口,
//  底层采用asm字节码生成框架生成代理类的字节码,
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();

        enhancer.setSuperclass(UserServiceImpl.class);
        enhancer.setCallback(new MyMethodInterceptor());

        UserServiceImpl userService = (UserServiceImpl) enhancer.create();
        userService.add();
    }
//  代理对象的生成过程由Enhancer类实现,大概步骤如下:
//  1、生成代理类Class的二进制字节码;
//  2、通过Class.forName加载二进制字节码,生成Class对象;
//  3、通过反射机制获取实例构造,并初始化代理类对象。

//  1、代理类UserService$$EnhancerByCGLIB$$394dddeb继承了委托类UserSevice,且委托类的final方法不能被代理;
//  2、代理类为每个委托方法都生成两个方法,以add方法为例,一个是重写的add方法,一个是CGLIB$add$0方法,该方法直接调用委托类的add方法;
//  3、当执行代理对象的add方法时,会先判断是否存在实现了MethodInterceptor接口的对象cglib$CALLBACK_0,如果存在,则调用MethodInterceptor对象的intercept方法:

}

jdk和cglib动态代理实现的区别
1、jdk动态代理生成的代理类和委托类实现了相同的接口;
2、cglib动态代理中生成的字节码更加复杂,生成的代理类是委托类的子类,且不能处理被final关键字修饰的方法;
3、jdk采用反射机制调用委托类的方法,cglib采用类似索引的方式直接调用委托类方法;

猜你喜欢

转载自blog.csdn.net/u010503822/article/details/78793870