CGLib 框架简单

CGLib 是一个强大、高性能和高质量的代码生成库,它用于在运行时扩展 Java 类和实现接口。

CGLib 是一个强大、高性能和高质量的代码生成库,它用于在运行时扩展 Java 类和实现接口。CGLib 被广泛应用于 AOP 框架中,如:Spring Framework 框架,用以提供方法拦截操作。Hibernate 作为一个比较受欢迎的 ORM(对象关系映射)框架,同样使用CGLib 来代理单端(多对一和一对一)关联。

CGLib 作为一个开源项目,其代码托管在 github,地址为:

https://github.com/cglib/cglib 

为什么选择 CGLib?

CGLib 代理主要通过对字节码的操作,为对象引入间接级别,以控制对象的访问。

我们知道 Java 中有一个动态代理也是做这个事情的,那我们为什么不直接使用 Java 动态代理,而要使用 CGLib 呢?答案是 CGLib 相比于 JDK 动态代理更加强大。JDK 动态代理虽然简单易用,但是其有一个致命缺陷是,只能对接口进行代理。如果要代理的类为一个普通类、没有接口,那么 JDK 动态代理就没法使用了。

CGLib 组成结构

CGLib 框架简单

图1:CGLib 组成结构

CGLib 底层使用了 ASM(一个短小精悍的字节码操作框架)来操作字节码生成新的类。除了 CGLib 库外,脚本语言(如 Groovy 和 BeanShell)也使用 ASM 生成字节码。ASM 使用类似 SAX 的解析器来实现高性能。我们不鼓励直接使用 ASM,因为它需要对 Java 字节码的格式足够的了解。

示例

上面说了这么多,你可能还是不知道 CGLib 是干什么的,下面通过一个具体的例子来介绍 CGLib 的用法。假如我们有一个 HelloWorld 类,该类有一个 test() 方法。然后,通过 CGLib 为 HelloWorld 创建一个代理对象,实现在调用 test() 方法前后打印字符串到控制台。代码如下:

(1)添加 Maven 依赖

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

(2)HelloWorld.java 类

/**
 * 被代理的类
 * @author hxstrive.com 2021/12/29
 */
public class HelloWorld {

    public void test(){
        System.out.println("hello world");
    }

}

(3)CglibHello.java 类

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

/**
 * 第一个 CGLib 示例,使用 CGLib 创建 {@link HelloWorld} 类的代理对象
 * @author hxstrive.com 2021/12/28
 */
public class CglibHello {

    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(HelloWorld.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args,
                                    MethodProxy proxy) throws Throwable {
                System.out.println("before method run...");
                Object result = proxy.invokeSuper(obj, args);
                System.out.println("after method run...");
                return result;
            }
        });

        HelloWorld sample = (HelloWorld) enhancer.create();
        sample.test();
    }

}

运行程序,输出如下:

before method run...
hello world
after method run...
业精于勤,荒于嬉。——韩愈《进学解》
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号