最新公告
  • 欢迎您光临极客文库,登录获取更多编程学习资源及文章!立即加入我们
  • Spring AOP的底层实现之CGLIB的动态代理

    使用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 SpringDemo2 {
    
        @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只支持方法链接点,不提供属性连接。

    本站所有文章均由网友分享,仅用于参考学习用,请勿直接转载,如有侵权,请联系网站客服删除相关文章。若由于商用引起版权纠纷,一切责任均由使用者承担
    极客文库 » Spring AOP的底层实现之CGLIB的动态代理

    常见问题FAQ

    如果资源链接失效了怎么办?
    本站用户分享的所有资源都有自动备份机制,如果资源链接失效,请联系本站客服QQ:2580505920更新资源地址。
    如果用户分享的资源与描述不符怎么办?
    可以联系客服QQ:2580505920,如果要求合理可以安排退款或者退赞助积分。
    如何分享个人资源获取赞助积分或其他奖励?
    本站用户可以分享自己的资源,但是必须保证资源没有侵权行为。点击个人中心,根据操作填写并上传即可。资源所获收益完全归属上传者,每周可申请提现一次。
    如果您发现了本资源有侵权行为怎么办?
    及时联系客服QQ:2580505920,核实予以删除。

    参与讨论

    • 108会员总数(位)
    • 3698资源总数(个)
    • 3本周发布(个)
    • 0 今日发布(个)
    • 202稳定运行(天)

    欢迎加入「极客文库」,成为原创作者从这里开始!

    立即加入 了解更多
    成为赞助用户享有更多特权立即升级