• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

Spring AOP的底层实现之CGLIB的动态代理

编程语言 Geekerstar 10个月前 (05-29) 581次浏览 已收录 0个评论 扫描二维码
文章目录[隐藏]

使用CGLIB生成代理

对于不使用接口的业务类,无法使用JDK动态代理。

CGlib采用非常底层字节码技术,可以为一个类创建子类,解决无接口代理问题。

代码实现

新建一个包demo2,创建一个类ProductDao

package com.jikewenku.aop.demo2;

public class ProductDao {
    public void save(){
        System.out.println("保存商品...");
    }

    public void update(){
        System.out.println("修改商品...");
    }

    public void delete(){
        System.out.println("删除商品...");
    }

    public void find(){
        System.out.println("查询商品...");
    }
}

传统方法和上一节一样,我们这里就不演示了,现在我们仍然是要对save方法做一个权限校验。

创建一个类MyCglibProxy

package com.jikewenku.aop.demo2;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class MyCglibProxy implements MethodInterceptor{

    private ProductDao productDao;

    public MyCglibProxy(ProductDao productDao){
        this.productDao = productDao;
    }

    public Object createProxy(){
        // 1.创建核心类
        Enhancer enhancer = new Enhancer();
        // 2.设置父类
        enhancer.setSuperclass(productDao.getClass());
        // 3.设置回调
        enhancer.setCallback(this);
        // 4.生成代理
        Object proxy = enhancer.create();
        return proxy;
    }

    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        if("save".equals(method.getName())){
            System.out.println("权限校验===================");
            return methodProxy.invokeSuper(proxy,args);
        }
        return methodProxy.invokeSuper(proxy,args);
    }
}

创建一个测试类

package com.jikewenku.aop.demo2;

import org.junit.Test;

public class <a href="https://www.jikewenku.com/tag/spring" title="查看更多关于Spring的文章" target="_blank">Spring</a>Demo2 {

    @Test
    public void demo1(){
        ProductDao productDao = new ProductDao();

        ProductDao proxy = (ProductDao) new MyCglibProxy(productDao).createProxy();
        proxy.save();
        proxy.update();
        proxy.delete();
        proxy.find();
    }
}

运行程序,输出结果正确,保存之前进行了权限校验

代理知识总结

Spring在运行期,生成动态代理对象,不需要特殊的编译器

Spring AOP的底层就是通过JDK动态代理或CGLib动态代理技术为目标Bean执行横向织入

1、若目标对象实现了若干接口,Spring使用JDK的java.lang.reflect.Proxy类代理。

2、若目标对象没有实现任何接口,Spring使用CGLib库生成目标对象的子类。

程序中应优先对接口创建代理,便于程序解耦维护

标记为final的方法,不能被代理,因为无法进行覆盖

– JDK动态代理是针对接口生成子类,接口中方法不能使用final修饰

– CGLib是针对目标类生产子类,因此类或方法不能使用final

Spring只支持方法链接点,不提供属性连接。


丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:Spring AOP的底层实现之CGLIB的动态代理
喜欢 (0)
[247507792@qq.com]
分享 (0)
Geekerstar
关于作者:
本站技术支持

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00