logo

静态代理、JDK动态代理与CGLIB动态代理:深入解析

作者:JC2024.01.05 12:04浏览量:5

简介:本文将深入解析静态代理、JDK动态代理与CGLIB动态代理的概念、实现原理和适用场景,帮助读者更好地理解这三种代理机制。

在面向对象编程中,代理模式是一种常用的设计模式,用于在不改变原始类代码的情况下扩展类的功能。代理模式通过创建一个新的类来封装对原始对象的访问,从而实现额外的功能或处理。根据实现方式的不同,代理可以分为静态代理和动态代理。而动态代理又可以分为JDK动态代理和CGLIB动态代理。下面我们将分别介绍这三种代理机制。
一、静态代理
静态代理是指代理类与被代理类在编译时就确定了关系。代理类与被代理类通常具有相同的方法和字段,除了代理类会额外包含对被代理类的引用。通过这个引用,代理类可以调用被代理类的方法,并在调用前后添加额外的逻辑。
例如,假设我们有一个计算器类Calculator,现在我们想要创建一个代理类ProxyCalculator,在每次执行计算时记录日志。我们可以如下实现:

  1. public class Calculator {
  2. public int add(int a, int b) {
  3. return a + b;
  4. }
  5. }
  6. public class ProxyCalculator extends Calculator {
  7. private Calculator calculator;
  8. public ProxyCalculator(Calculator calculator) {
  9. this.calculator = calculator;
  10. }
  11. @Override
  12. public int add(int a, int b) {
  13. // 记录日志
  14. System.out.println("Before add");
  15. int result = calculator.add(a, b);
  16. // 记录日志
  17. System.out.println("After add");
  18. return result;
  19. }
  20. }

在上述代码中,ProxyCalculator作为Calculator的代理类,通过继承Calculator并重写其方法实现了额外的日志记录功能。
二、JDK动态代理
JDK动态代理是Java提供的一种实现动态代理的机制。与静态代理不同,JDK动态代理不需要手动创建代理类,而是通过反射机制在运行时动态生成代理类。JDK动态代理主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口实现。
下面是一个简单的JDK动态代理示例:
java import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxyExample { public static void main(String[] args) { // 定义被代理类 Calculator calculator = new Calculator(); // 创建动态代理对象 Calculator proxy = (Calculator) Proxy.newProxyInstance( Calculator.class.getClassLoader(), Calculator.class.getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\n在上述代码中,我们首先创建了一个`Calculator`对象作为被代理对象。然后,通过`Proxy.newProxyInstance()`方法创建了一个动态代理对象`proxy`。这个方法接受三个参数:类加载器、接口数组和一个实现了`InvocationHandler`接口的对象。在`InvocationHandler`的实现中,我们重写了`invoke()`方法,该方法会在每次调用被代理对象的方法时被调用。在`invoke()`方法中,我们可以添加额外的逻辑,比如记录日志或进行权限控制等。 三、CGLIB动态代理 CGLIB(Code Generation Library)是一个高性能、高质量的代码生成库,它可以扩展Java类与实现Java接口。CGLIB通过在运行时动态生成子类的方式来实现代理,因此它比JDK动态代理更加灵活。由于CGLIB需要生成子类,因此它不能用于实现接口,只能用于继承类。 下面是一个简单的CGLIB动态代理示例:java
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.apache.commons.logging.LogFactory;
public class CglibProxyExample {\n在上述代码中,我们首先创建了一个Enhancer对象作为CGLIB的增强器。然后,通过调用Enhancercreate()方法来创建一个新的子

相关文章推荐

发表评论