cglib动态代理

概念及特点

  • 使用CGLib实现动态代理,依赖cglib-x.x.x.jar
  • 原理是对指定的业务类动态生成一个子类,并覆盖其中业务方法实现代理
  • 针对类来实现代理的,完全不受代理类必须实现接口的限制
  • CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类
  • 因为采用的是继承,所以不能对final修饰的类进行代理,不能对声明为final的方法进行代理

组成

  • 业务实现类 负责实现主要的业务方法(不需要实现接口)
  • 实现拦截接口MethodInterceptor,创建动态代理类

案例演示

  1. 引入cglib

        <dependencies>
            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>2.2.2</version>
            </dependency>
        </dependencies>
    
  2. 业务实现类

    public class AccountServiceImpl {
        public void queryAccount() {
            System.out.println("查看账户...");
        }
    
        public void updateAccount() {
            System.out.println("修改账户...");
        }
    }
    
  3. 方法拦截器

    public class CglibProxy implements MethodInterceptor {
        private Object target;//业务类对象,供代理方法中进行真正的业务方法调用
    
        //相当于JDK动态代理中的绑定
        public Object getInstance(Object target) {
            this.target = target;  //给业务对象赋值
            Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类
            enhancer.setSuperclass(this.target.getClass());  //为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)
            //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦截
            enhancer.setCallback(this);
            // 创建动态代理类对象并返回
            return enhancer.create();
        }
    
        // 实现回调方法
        @Override
        public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("预处理——————");
            proxy.invokeSuper(target, args); //调用业务类(父类中)的方法
            System.out.println("调用后操作——————");
            return null;
        }
    }
    
    1. 业务调用
      public class CglibProxyApplication {
          public static void main(String[] args) {
              AccountServiceImpl accountServiceImpl=new AccountServiceImpl();
              CglibProxy  cglib=new CglibProxy();
              AccountServiceImpl accountServiceProxy=(AccountServiceImpl)cglib.getInstance(accountServiceImpl);
              accountServiceProxy.queryAccount();
              accountServiceProxy.updateAccount();
          }
      }
    

两种动态代理对比

  1. 机制区别
  • jdk动态代理是通过接口中的方法名,在动态生成的代理类中调用业务实现类的同名方法;利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类;
  • cglib动态代理是通过继承业务类,生成的动态代理类是业务类的子类,通过重写业务方法进行代理;cglib底层采用ASM字节码生成框架,使用字节码技术生成代理类;
  1. 效率对比
  • jdk6之前,cglib效率过于jdk反射
  • 调用次数较少时,jdk6、jdk7优于cglib
  • 调用次数较多时,jdk6、jdk7反射效率低于cglib
  • jdk8 动态代理优于cglib效率
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章