zoukankan      html  css  js  c++  java
  • CGLIB动态代理

    1、概述

    我们知道,Java动态代理使用起来非常简单,但也有其局限性。使用Java动态代理时,被代理的类必须实现一个或多个接口,若想给没有实现接口的类实现动态代理,就需要使用CGLIB动态代理。

    CGLIB(Code Generation Library)是一个高性能开源代码生成包,它的底层通过ASM(Java字节码操控框架)来转换字节码,为一个类创建子类,然后对子类进行增强,解决无接口代理问题。CGLIB要依赖ASM的jar包

    2、实例分析

    这里为了图简便,笔者直接导入了spring-core-4.0.6.RELEASE.jar包。

    ①定义目标类(被代理对象)

    class Book{
        public void insert(){
            System.out.println("增加");
        }
    
        public void delete(){
            System.out.println("删除");
        }
    
        public void update(){
            System.out.println("修改");
        }
    
        public void select(){
            System.out.println("查询");
        }
    }

    分析:目标类中定义了四个CRUD方法。

    ②定义切面类(增强的方法)

    class Aspect{
        public void before(){
            System.out.println("方法执行前");
        }
    
        public void after(){
            System.out.println("方法执行后");
        }
    }

    ③主程序

    import java.lang.reflect.Method;
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    /**
     * @author Hanlin Wang
     */
    
    public class Cglib {
        public static void main(String[] args) {
            final Book book = new Book();
    
            final Aspect aspect = new Aspect();
    
            Enhancer enhancer = new Enhancer();
    
            enhancer.setSuperclass(Book.class);
    
            enhancer.setCallback(new MethodInterceptor() {
    
                @Override
                public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                    aspect.before();
    
                    Object obj = method.invoke(book, args);
    
                    aspect.after();
    
                    return obj;
                }
            });
    
            Book proxyTarget = (Book) enhancer.create();
    
            proxyTarget.insert();
    
            System.out.println("-----------");
    
            proxyTarget.delete();
    
            System.out.println("-----------");
    
            proxyTarget.update();
    
            System.out.println("-----------");
    
            proxyTarget.select();
        }
    }

    运行结果:

    方法执行前
    增加
    方法执行后

    方法执行前
    删除
    方法执行后

    方法执行前
    修改
    方法执行后

    方法执行前
    查询
    方法执行后

    CGLIB的核心类:Enhancer

    注意:上述代码的new MethodInterceptor使用了匿名内部类来实现MethodInterceptor接口。接口中若应用到其他变量,这些变量必须被final关键字修饰,否则编译不通过。

    建议大家与笔者的另一篇博文《Java动态代理》作比较。

  • 相关阅读:
    记MongoDB的安装
    Python格式化输出指定宽度及占位符
    LMDB数据库加速Pytorch文件读取速度
    IDEA设置输入后自动提示
    IDEA2020 最新激活
    java 编译执行cmd命令
    算法9:What is the sum of the digits of the number 21000
    JAVA8 LocalDateTime
    算法8:已知 a^2+b^2=c^2(a,b,c 为自然数,a<b<c),且a+b+c=1000,求abc的值?
    ROS学习笔记
  • 原文地址:https://www.cnblogs.com/wanxi/p/6476208.html
Copyright © 2011-2022 走看看