当前位置: 首页 > 知识库问答 >
问题:

Spring JDK动态代理和CGLIB-实现细节

司马腾
2023-03-14

我的问题与“代理内部的自我调用问题”有关,但不是我的问题。(我已经找到了该问题的一些解决方案,例如这里所描述的)。我还找到了为什么会发生这种情况的基本解释,这里

class Service {
    Service self;

    public Service() {
       // I don't like this because it makes my Service to be aware of the fact that it's a proxy. I just wanted my class to be a pojo with annotations
       self = AopContext.currentProxy();
    }

    @Audit
    public CustomClassContainingTheValuesToAudit getValuesFromServer() {
       CustomClassContainingTheValuesToAudit c;
       try {
           Object answer = self.doGetValuesFromServer();
           c = ... ; // create what to audit based on the answer
       } catch (...) {
          // log the fact that you didn't have enough privileges to run doGetValuesFromServer()
          // create c based on the exception I got
          c = ...;
       }
       return c; // object to be audited
    }

   @PreAuthorize(.....)
   public Object doGetValuesFromServer() {
       .........
   }
} 

1)根据我现在对代码外观的描述,您会怎么做来避免从上下文中获取bean?我不想将每个服务分成两个类,以避免自调用问题。我想要一种方法来使aspectJ和预授权工作如所描述的那样。2)我不明白为什么CGLIB以它的方式实现代理。所以假设我有我的类服务

class Service {
    public void methodA(){
        // do methodA stuff
        // call method b
        methodB();
    }
    public void methodB(){
        // do methodB stuff
    }
}

那么GCLIB将生成如下类:

class Service$CGLIB extends Service {
// it's only extending my class to make it compatible with the variable where i'm storing/autowiring the proxy
   Service privateField; // but it's actually using a decorator pattern, just like JDK Dynamic Proxies do
   public void methodA() {
      // do any magic before
      privateField.a();
      // any magic after the call
   }

   public void methodB() {
       // magic
       privateField.b();
       // some more magic
   }
}

为什么CGLIB不直接调用super.a()和super.b()?为什么它需要装饰而不是委托?我想我所需要的是代理委托给Super。我是这样做的,我没有任何问题的自我调用,因为多元主义。是否有一个代理的实现来完成我所期望的CGLIB所做的工作?

共有1个答案

柳德义
2023-03-14

cglib代理的行为与cglib的工作方式无关,而是与Spring如何使用cglib有关。Cglib可以委托或子类化调用。看看Spring的DynamicAdvisedInterceptor,它实现了这个委派。使用MethodProxy,它可以执行超级方法调用。

Spring定义了委派而不是子类化,以便最大限度地减少使用Cglib或Java代理之间的差异。这简直就是做出的选择。

 类似资料:
  • 本文向大家介绍Java 动态代理与CGLIB详细介绍,包括了Java 动态代理与CGLIB详细介绍的使用技巧和注意事项,需要的朋友参考一下 静态代理模式 因为需要对一些函数进行二次处理,或是某些函数不让外界知道时,可以使用代理模式,通过访问第三方,间接访问原函数的方式,达到以上目的。 1.1 静态代理的弊端 如果要想为多个类进行代理,则需要建立多个代理类,维护难度加大。 仔细想想,为什么静态代理会

  • 本文向大家介绍浅谈Java代理(jdk静态代理、动态代理和cglib动态代理),包括了浅谈Java代理(jdk静态代理、动态代理和cglib动态代理)的使用技巧和注意事项,需要的朋友参考一下 一、代理是Java常用的设计模式,代理类通过调用被代理类的相关方法,并对相关方法进行增强。加入一些非业务性代码,比如事务、日志、报警发邮件等操作。 二、jdk静态代理 1、业务接口 2、业务实现类 3、代理类

  • 本文向大家介绍spring cglib 与 jdk 动态代理,包括了spring cglib 与 jdk 动态代理的使用技巧和注意事项,需要的朋友参考一下 1. 概述 JDK动态代理是利用java反射机制 生成一个实现接口的匿名类, 在调用具体方法前调用InvocationHandler来处理 Cglib动态代理是 利用asm开源包 把被代理类的class文件加载进来 通过修改其字节码生成子类来处

  • 问题内容: 如果是代理设计模式,那么JDK的动态代理和第三方动态代码生成API(例如CGLib)有什么区别? 使用这两种方法之间的区别是什么?何时应该优先选择另一种方法? 问题答案: JDK动态代理只能按接口进行代理(因此,您的目标类需要实现一个接口,然后该接口也可以由代理类实现)。 CGLIB(和javassist)可以通过子类化创建代理。在这种情况下,代理将成为目标类的子类。无需接口。 因此,

  • 在代理设计模式的情况下,jdk的动态代理和第三方的动态代码生成API(如cglib)有什么区别? 使用这两种方法之间有什么区别?什么时候应该选择一种方法而不是另一种方法?

  • 本文向大家介绍Spring中JDK动态代理和CGLib代理之间的区别,包括了Spring中JDK动态代理和CGLib代理之间的区别的使用技巧和注意事项,需要的朋友参考一下 Spring AOP是基于代理的。Spring使用了两种代理策略,一种是JDK动态代理,另一种是CGLIB代理。 JDK提供了JDK动态代理。它只能是按接口的代理,因此目标类需要实现接口。在您实现一个或多个接口时,spring会