Spring framework(十三)CGLIB动态代理

一、概念

JDK动态代理的目标类必须实现一个或者多个接口,具有一定的局限性。如果不希望实现接口,可以使用CGLIB代理。

CGLIB(Code Generation Library)是一个高性能开源的代码生成包,它被许多AOP框架所使用,其底层是通过使用一个小而快的字节码处理框架ASM(Java字节码操控框架)转换字节码并生成新的类。使用CGLIB需要导入asm-x.x.jar和CGLIB-x.x.x.jar。如果已经导入spring-core-x.x.x.RELEASE.jar,就不用再单独导入这两个包了。

二、实例

public interface UserManager {

    void addUser(String name,String password);

    void delUser(String name);
}
public class UserManagerImpl implements UserManager {
    @Override
    public void addUser(String name, String password) {
        System.out.println("添加用户:"+name+",密码:"+password);
    }

    @Override
    public void delUser(String name) {
        System.out.println("删除用户:"+name);
    }
}
public class MyAspect {

    public void myBefore(){
        System.out.println("方法执行前调用");
    }

    public void myAfter(){
        System.out.println("方法执行后调用");
    }

}
public class CglibProxy implements MethodInterceptor{
    //需要代理的目标对象
    private Object target;
    final MyAspect myAspect=new MyAspect();

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        myAspect.myBefore();
        Object invoke = method.invoke(target, objects);
        myAspect.myAfter();
        return invoke;
    }

    public Object getCglibProxy(Object objectTarget){
        this.target=objectTarget;
        Enhancer enhancer=new Enhancer();
        //CGLIB是针对指定的类生成一个子类,所以需要指定父类
        enhancer.setSuperclass(objectTarget.getClass());
        enhancer.setCallback(this);
        Object result = enhancer.create();
        return result;
    }

    public static void main(String[] args) {
        CglibProxy cglibProxy=new CglibProxy();
        UserManager user = (UserManager) cglibProxy.getCglibProxy(new UserManagerImpl());
        user.addUser("王者","123456");
        user.delUser("王者");
    } 
}

执行结果:

在这里插入图片描述

三、JDK代理和CGLIB代理的区别

jdk动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。CGLIB动态代理是利用ASM开源包,加载代理对象类的class文件,通过修改其字节码生成子类来处理。

JDK动态代理只能对实现了接口的类生成代理,而不能针对类。
CGLIB针对类实现代理,主要是指对指定类生成一个子类,覆盖其中的方法。因为是继承,所以该类或方法不能是final类型。

JDK动态代理特点:

  • 代理对象必须实现一个或者多个接口
  • 以接口的形式接收代理实例,而不是代理类

CGLIB动态代理特点:

  • 代理对象不能被final修饰
  • 以类或者接口形式接受代理实例

JDK与CGLIB性能对比:
生成代理实例:JDK>CGLIB
代理实例运行:JDK>CGLIB

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑谈子云亭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值