【问题标题】:When and how cglib-proxied component instance is created何时以及如何创建 cglib 代理的组件实例
【发布时间】:2020-01-17 07:11:30
【问题描述】:

我想了解 CGLIB 包装(代理)Spring 组件是否存在一些规则/条件。以这种情况为例:

@Component
public class TestComponent {
}

@Service
//@Transactional(rollbackFor = Throwable.class)
public class ProcessComponent {

    @Autowired
    private TestComponent testComponent;

    public void doSomething(int key) {
      // try to debug "testComponent" instance here ...
    }

}

如果我们让它这样并调试方法内的testComponent 字段,那么我们将看到它没有被CGLIB 包装。

现在,如果我们取消注释 @Transactional 注释并进行调试,我们会发现实例已被包装:它的类型为 ProcessComponent$$EnhancerByCGLIB$$14456 或类似的类型。这显然是因为 Spring 需要创建一个代理类来处理事务支持。

但我想知道,有什么方法可以检测到这种包装是如何以及何时发生的?例如,在 Spring 的源代码中的一些特定位置进行调试以查找更多信息;或有关他们如何决定创建代理的规则的一些文档。

为了您的信息,我需要知道这一点,因为我的应用程序中的某些组件(不是@Transactional,上面的示例只是为了演示目的突然出现 成为代理(我在过去发现了一个没有的修订版)。最重要的问题是这会影响那些也包含public final 方法的组件,另一个问题(同样重要)是类的设计/结构中一定有一些意想不到的变化。对于这类问题,我们当然必须尝试找出发生了什么/谁做了导致这种情况的改变等等......

请注意,我们刚刚将应用程序从 Spring Boot 2.1.0RELEASE 升级到 2.1.10RELEASE。而且到现在为止逐个修订检查代码修订是不可行的,因为已经有相当多的提交了。

任何形式的帮助都将不胜感激,在此先感谢。

【问题讨论】:

  • 在 org.springframework 级别打开调试或跟踪日志记录将有助于作为起点。
  • @PaulNUK 是否有我们需要注意的日志行模式?
  • 任何与 AOP 相关的东西都会导致创建代理。所以@ASync@Transactional 等,所以如果没有看到该课程,这个问题或多或少太宽泛而无法回答。

标签: java spring spring-boot cglib


【解决方案1】:

您可以调试到 org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(Class, String, TargetSource)。 如果找到任何顾问,该 bean 将被代理。

【讨论】:

  • 非常感谢您的提示,这正是帮助我找到根本原因的原因!我们团队中有人在该类的层次结构中为根抽象类添加了一个方面,这导致了代理的创建。
【解决方案2】:

如果你使用@Lookup 方法注入,它也会代理组件类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多