何时以及如何创建 cglib-proxied 组件实例

When and how cglib-proxied component instance is created

我想了解 Spring 组件是否由 CGLIB 包装(代理)的某些规则/条件。例如,以这种情况为例:

@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$456 或类似的类型。这显然是因为 Spring 需要创建一个代理 class 来处理事务支持。

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

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

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

如有任何帮助,我们将不胜感激,在此先致谢。

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

如果您使用 @Lookup 方法注入,它还会代理组件 class。