CGLIB与JDK动态代理不同之处说明

欣喜 Java经验 发布时间:2025-03-24 10:50:12 阅读数:4552 1
下文笔者讲述 CGLIB与JDK动态代理 不同之处,如下所示

CGLIB与JDK动态代理比较

| 特性                | JDK 动态代理                                      | CGLIB 动态代理                                      |
|---------------------|---------------------------------------------------|---------------------------------------------------|
| 代理对象类型        | 代理接口                                          | 代理类(继承目标类)                              |
| 目标类要求          | 目标类必须实现至少一个接口                        | 目标类可以不实现接口,但不能是 `final` 的         |
| 性能                | 通常比 CGLIB 慢,因为需要通过反射调用接口方法     | 通常比 JDK 动态代理快,因为直接调用方法           |
| 使用场景            | 代理接口实现                                      | 代理类实现,特别是没有实现接口的类                |
| 字节码操作          | 使用反射                                          | 使用 ASM 进行字节码操作                           |

使用CGLIB代理类

1.定义目标类
public class TargetClass {
    public void sayHello() {
        System.out.println("Hello from TargetClass!");
    }
}

2.定义拦截器
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before method: " + method.getName());
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("After method: " + method.getName());
        return result;
    }
}

3.创建代理类并使用
import net.sf.cglib.proxy.Enhancer;

public class CglibExample {
    public static void main(String[] args) {
        // 创建 Enhancer 对象
        Enhancer enhancer = new Enhancer();
        // 设置目标类
        enhancer.setSuperclass(TargetClass.class);
        // 设置拦截器
        enhancer.setCallback(new MyMethodInterceptor());

        // 创建代理类的实例
        TargetClass proxyInstance = (TargetClass) enhancer.create();

        // 调用代理类的方法
        proxyInstance.sayHello();
    }
}

代码说明

1.定义目标类
    public class TargetClass {
        public void sayHello() {
            System.out.println("Hello from TargetClass!");
        }
    }
    - `TargetClass`:目标类,包含要代理的方法 `sayHello`。

2.定义拦截器:
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;

    import java.lang.reflect.Method;

    public class MyMethodInterceptor implements MethodInterceptor {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("Before method: " + method.getName());
            Object result = proxy.invokeSuper(obj, args);
            System.out.println("After method: " + method.getName());
            return result;
        }
    }
    - `MyMethodInterceptor`:实现 `MethodInterceptor` 接口。
    - `intercept` 方法:在目标方法调用前后添加额外的逻辑。

3.创建代理类并使用:
    import net.sf.cglib.proxy.Enhancer;

    public class CglibExample {
        public static void main(String[] args) {
            // 创建 Enhancer 对象
            Enhancer enhancer = new Enhancer();
            // 设置目标类
            enhancer.setSuperclass(TargetClass.class);
            // 设置拦截器
            enhancer.setCallback(new MyMethodInterceptor());

            // 创建代理类的实例
            TargetClass proxyInstance = (TargetClass) enhancer.create();

            // 调用代理类的方法
            proxyInstance.sayHello();
        }
    }
    -创建 `Enhancer` 对象:
	    `Enhancer` 是 CGLIB 的核心类,
		 用于生成代理类。
    -设置目标类:
	     `enhancer.setSuperclass(TargetClass.class)` 
		   设置要代理的目标类。
    -设置拦截器:
	     `enhancer.setCallback(new MyMethodInterceptor())` 
		   设置拦截器。
    -创建代理类的实例:
	     `enhancer.create()` 
		   创建代理类的实例。
    -调用代理类的方法:
	      `proxyInstance.sayHello()`调用代理类的方法,
		   拦截器会在方法调用前后添加额外的逻辑

代码输出信息

Before method: sayHello
Hello from TargetClass!
After method: sayHello

内部实现细节

1.生成代理类:
   - CGLIB 使用 ASM 库生成目标类的子类。
   - 生成的子类会重写目标类的方法。

2.拦截器调用:
   - 当代理类的方法被调用时
      会先调用拦截器`intercept` 方法。
   - 在 `intercept` 方法中
      可以添加额外的逻辑(如日志记录、权限检查等)。
   - 使用 `MethodProxy.invokeSuper` 调用目标类的方法。

3.字节码操作:
   - CGLIB 使用 ASM 库进行字节码操作,
      生成新的类文件。
   - 生成的类文件会在运行时加载到JVM 中
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaJingYan/202503/17427846458394.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者