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动态代理》作比较。

  • 相关阅读:
    flex 只显示年、月的日期选择控件(TimeChooser)
    SQL 实现统计业务
    SQL 时间函数详解
    我与计算机
    ISE中FPGA的实现流程
    总结Verilog中always语句的使用
    VGA 时序标准
    ChipScope软件使用
    FIFO的使用场景
    Verilog 初级入门概念
  • 原文地址:https://www.cnblogs.com/wanxi/p/6476208.html
Copyright © 2011-2022 走看看