深入探讨Java中的JDK代理与CGLIB代理

上一篇 / 下一篇  2024-01-04 10:39:31

  在Java开发中,代理是一种常见的设计模式,它可以为我们提供一种灵活的方式来控制对象的访问和操作。在代理模式中,JDK代理与CGLIB代理是两种常用的实现方式,它们分别基于Java动态代理和CGLIB字节码生成技术。本文将深入探讨这两种代理方式的原理、特点以及使用场景。
  JDK代理
  JDK代理是Java动态代理的一种典型实现方式。它基于Java反射机制,在运行时动态地创建代理类和实例。JDK代理要求被代理的类必须实现一个或多个接口,代理类会实现这些接口并在方法调用前后插入额外的逻辑。下面是一个简单的JDK代理示例:
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Method;
  import java.lang.reflect.Proxy;
  interface Subject {
      void request();
  }
  class RealSubject implements Subject {
      public void request() {
          System.out.println("RealSubject - Request");
      }
  }
  class DynamicProxy implements InvocationHandler {
      private Object target;
      public DynamicProxy(Object target) {
          this.target = target;
      }
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
          System.out.println("Before request");
          Object result = method.invoke(target, args);
          System.out.println("After request");
          return result;
      }
  }
  public class ProxyTest {
      public static void main(String[] args) {
          RealSubject realSubject = new RealSubject();
          InvocationHandler handler = new DynamicProxy(realSubject);
          Subject proxySubject = (Subject) Proxy.newProxyInstance(
                  realSubject.getClass().getClassLoader(),
                  realSubject.getClass().getInterfaces(),
                  handler
          );
          proxySubject.request();
      }
  }
  CGLIB代理
  CGLIB(Code Generation Library)代理是另一种常见的代理方式,它不要求被代理的类实现接口,而是通过生成目标类的子类来实现代理。CGLIB利用字节码生成技术,通过修改字节码的方式在运行时动态创建代理类。下面是一个简单的CGLIB代理示例:
  import net.sf.cglib.proxy.MethodInterceptor;
  import net.sf.cglib.proxy.MethodProxy;
  import net.sf.cglib.proxy.Enhancer;
  class RealSubject {
      public void request() {
          System.out.println("RealSubject - Request");
      }
  }
  class DynamicProxy implements MethodInterceptor {
      public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
          System.out.println("Before request");
          Object result = proxy.invokeSuper(obj, args);
          System.out.println("After request");
          return result;
      }
  }
  public class ProxyTest {
      public static void main(String[] args) {
          Enhancer enhancer = new Enhancer();
          enhancer.setSuperclass(RealSubject.class);
          enhancer.setCallback(new DynamicProxy());
          RealSubject proxySubject = (RealSubject) enhancer.create();
          proxySubject.request();
      }
  }
  JDK代理与CGLIB代理的比较
  1. 实现方式: JDK代理基于接口,要求目标类实现接口;而CGLIB代理通过继承目标类生成子类。
  2. 性能: JDK代理在创建代理对象时相对较慢,因为它需要反射和实现接口;而CGLIB代理在创建对象时更快,因为它直接生成字节码。
  3. 目标类要求: JDK代理要求目标类实现接口,不适用于没有接口的类;而CGLIB代理可以代理没有实现接口的类。
  4. 内存占用: JDK代理生成的代理类较轻量,占用内存相对较少;而CGLIB代理生成的子类可能较重,占用内存相对较多。
  使用场景
  JDK代理适用于:
  ·目标类实现了接口。
  · 代理类不需要对目标类进行增强的情况。
  CGLIB代理适用于:
  · 目标类没有实现接口。
  · 需要对目标类进行增强,例如在目标方法前后插入额外的逻辑。
  总的来说,JDK代理和CGLIB代理各有优缺点,根据实际需求选择合适的代理方式是至关重要的。在项目中,有时也会结合两者使用,以充分发挥各自的优势。希望本文能够帮助读者更深入地理解和使用JDK代理与CGLIB代理。

TAG: 软件开发 Java java

 

评分:0

我来说两句

Open Toolbar