spring动态代理技术有哪些

回复

共3条回复 我来回复
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    Spring动态代理技术主要有两种实现方式:JDK动态代理和CGLIB动态代理。

    1. JDK动态代理
      JDK动态代理是通过接口来实现的动态代理,要求被代理的类必须实现至少一个接口。它的核心是利用Java的反射机制在运行时创建一个实现被代理接口的匿名类,并在其中调用被代理方法。JDK动态代理的步骤包括:首先定义一个InvocationHandler接口的实现类,然后通过Proxy类的静态方法newProxyInstance()来创建代理对象。

    优点:

    • 简单易用,不需要额外的依赖库
    • 被代理的类只需要实现接口即可

    缺点:

    • JDK动态代理只能对实现了接口的类进行代理,无法对没有实现接口的类进行代理
    • JDK动态代理只能代理接口中的方法,无法代理类中的方法
    • 生成的代理类相对较慢
    1. CGLIB动态代理
      CGLIB动态代理是通过继承被代理类来实现的动态代理,它无需被代理类实现接口。CGLIB动态代理的核心是使用字节码增强库ASM来动态生成被代理类的子类,并在子类中将方法进行拦截和委托。CGLIB动态代理的步骤包括:首先定义一个MethodInterceptor接口的实现类,然后通过Enhancer类的create()方法来创建代理对象。

    优点:

    • 可以对没有实现接口的类进行代理
    • 可以代理类中的方法,包括final方法

    缺点:

    • 生成的代理类较大,会占用更多的内存空间
    • CGLIB动态代理需要引入额外的CGLIB库作为依赖

    总结:
    JDK动态代理和CGLIB动态代理各有优缺点,选择哪种方式主要根据具体需求来决定。如果被代理类已经实现了接口,且代理的方法主要在接口中,可以选择JDK动态代理;如果被代理类没有实现接口,或者需要代理类中的非接口方法,可以选择CGLIB动态代理。

    1年前 0条评论
  • 不及物动词的头像
    不及物动词
    这个人很懒,什么都没有留下~
    评论

    Spring框架提供了多种动态代理技术,以下列举了其中一些常见的技术:

    1. JDK动态代理:JDK动态代理是基于接口的代理技术,它使用java.lang.reflect.Proxy类提供的方法来动态生成代理类。代理对象实现了目标接口,在方法调用时会被拦截,可以在方法前后添加额外的处理逻辑。JDK动态代理适用于基于接口的代理场景。

    2. CGLIB动态代理:CGLIB动态代理是基于类的代理技术,它通过动态生成子类来实现代理功能。代理对象继承了目标类,可以进行方法的重写和增强,无需目标类实现接口。CGLIB动态代理适用于无接口的代理场景。

    3. AspectJ切面编程:AspectJ是一个开源的切面编程框架,它能够在编译时或运行时将切面织入到目标对象的代码中。AspectJ提供了强大的切入点表达式语言,可以精确地指定在目标对象的哪些方法上进行切面织入。在Spring中可以通过引入AspectJ依赖和配置AspectJ注解来实现切面编程。

    4. Spring AOP:Spring AOP是Spring框架对AspectJ的封装和实现,它使用动态代理技术在运行时将切面织入到目标对象的方法中。Spring AOP支持基于方法执行的前置、后置、环绕和异常通知等常见切点,可以通过配置和注解的方式实现切面编程。

    5. 字节码增强工具:除了以上基于代理的动态代理技术,还有一些字节码增强工具可以实现动态代理,例如Byte Buddy和Javassist等。这些工具可以直接修改目标类的字节码来实现代理功能,具有更高的灵活性和性能,但使用起来相对复杂一些。

    总之,Spring框架提供了多种动态代理技术来实现切面编程和增强对象功能,开发者可以根据具体的需求选择合适的代理技术。

    1年前 0条评论
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    Spring动态代理技术主要有两种实现方式:JDK动态代理和CGLIB动态代理。

    一、JDK动态代理
    JDK动态代理是通过Java的反射机制来实现的。在Java标准库中,有一个Proxy类和一个InvocationHandler接口,可以用来创建代理对象和实现代理方法的调用。具体的步骤如下:

    1. 定义一个目标对象(被代理对象)和实现InvocationHandler接口的代理对象。
    2. 在代理对象的invoke方法中,使用反射调用目标对象的方法。

    具体的代码示例如下:

    public interface HelloService {
       void sayHello(String name);
    }
    
    public class HelloServiceImpl implements HelloService {
       public void sayHello(String name) {
          System.out.println("Hello, " + name);
       }
    }
    
    public class MyInvocationHandler implements InvocationHandler {
       private Object target;
       
       public MyInvocationHandler(Object target) {
          this.target = target;
       }
       
       @Override
       public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
          System.out.println("Before method: " + method.getName());
          Object result = method.invoke(target, args);
          System.out.println("After method: " + method.getName());
          return result;
       }
    }
    
    public class Main {
       public static void main(String[] args) {
          HelloService target = new HelloServiceImpl();
          MyInvocationHandler handler = new MyInvocationHandler(target);
          HelloService proxy = (HelloService) Proxy.newProxyInstance(Main.class.getClassLoader(),
                                                                 target.getClass().getInterfaces(),
                                                                 handler);
          proxy.sayHello("John");
       }
    }
    

    运行上述代码,输出结果为:

    Before method: sayHello
    Hello, John
    After method: sayHello

    二、CGLIB动态代理
    CGLIB动态代理是通过继承目标对象的方式来实现的。CGLIB(Code Generation Library)是一个强大的高性能的代码生成库,可以在运行时动态生成指定类的一个子类,并覆盖其中的方法来实现代理。具体的步骤如下:

    1. 引入CGLIB库的依赖。
    2. 创建一个MethodInterceptor接口的实现类,并在intercept方法中实现代理逻辑。
    3. 使用Enhancer类来创建代理对象,并将目标对象和MethodInterceptor实现类作为参数传入。

    具体的代码示例如下:

    // 目标对象
    public class HelloService {
       public void sayHello(String name) {
          System.out.println("Hello, " + name);
       }
    }
    
    // MethodInterceptor实现类
    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;
       }
    }
    
    // 创建代理对象
    public class Main {
       public static void main(String[] args) {
          Enhancer enhancer = new Enhancer();
          enhancer.setSuperclass(HelloService.class);
          enhancer.setCallback(new MyMethodInterceptor());
          HelloService proxy = (HelloService) enhancer.create();
          proxy.sayHello("John");
       }
    }
    

    运行上述代码,输出结果为:

    Before method: sayHello
    Hello, John
    After method: sayHello

    总结:

    • JDK动态代理适用于接口代理,通过Proxy类和InvocationHandler接口实现,利用Java的反射机制来实现代理。
    • CGLIB动态代理适用于类代理,通过继承目标对象的方式实现,利用CGLIB生成代理类的子类来覆盖目标方法。
    • 在选择使用哪种动态代理技术时,需要根据具体的需求和场景选择合适的方式。
    1年前 0条评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部