【问题标题】:Spring Weaving: @Configurable objects do not get woven correctly if used as a Parameter inside Methods of AutoproxiesSpring Weaving:@Configurable 对象如果用作自动代理方法中的参数,则无法正确编织
【发布时间】:2014-09-16 16:24:54
【问题描述】:

请考虑 spring 4.0.7 的以下情况

对于 Eclipselink,我们使用加载时间编织器。所以我们想同时使用@EnableSpringConfigured 和@EnableLoadTimeWeaving 来试验Springs @Configurable 注解。

这是功能齐全的,Spring-Beans 在构建过程中被完美地注入到 POJO 中。这个功能对我们很有帮助,因为我们希望在这些 POJO 中保留一些关于验证这些 POJO 的代码,而不是在 Bean 的其他地方。

我们的一些 Spring 上下文包含不实现任何接口的 Bean,因为它们是某些包的本地并且仅在那里使用。可以说,FooLogicBean 就是其中之一。如果要将其注入另一个 Bean,并且某些 Spring-AOP-Aspect (not-aspectj) (如某些性能测量方面)在执行路径中,则 Spring 将为 FooLogicBean 创建一个 CGLIB 自动代理并注入它。这功能齐全,效果也很好。

当我们想要在 FooLogicBean 的方法(如 fooLogicBean.doValidate(myPojo); )中实际使用带有 @Configurable 注释的 POJO 作为参数时,问题就出现了,分别是 CGLIB 代理。在这种情况下,一些重要的魔法阻止 POJO 通过 aspectj 编织(来自 spring-aspects 的 AnnotationBeanConfigurerAspect)。无论调用前面提到的 doValidate() 方法,它甚至从不编织在代码的任何地方。

如果我们在 FooLogicBean 中创建该 POJO,但不将其用作方法参数,则由于 @Configurable,它会再次被编织。

在不知道 Autoproxy 创建代码的情况下,我们假设一些花哨的 标记 例程会阻止 aspectj 检测到该类,如果该类已在 spring-aop 中使用。 use 在这种情况下意味着访问

有没有人尝试过这种晦涩的星座并知道解决方案?

提前致谢!

【问题讨论】:

  • 你能提供一个SSCCE吗?也许是一个成熟的 GitHub 项目?可再现性对于调试总是很好。

标签: spring aspectj spring-aop cglib spring-aspects


【解决方案1】:

代理是通过子类化创建的,即当您创建带注释的类Foo的代理时:

class Foo {
  @Bar
  void bar() { }
}

代理是通过实现一个类来创建的

class Foo$Proxy extends Foo {
  @Override
  void bar() { 
    // Proxy logic
  }
  // Overridden methods of Object
}

这使得Foo$Proxy 类成为Foo 的有效Liskov substitute。但是,正常的覆盖语义适用,即,诸如@Bar 之类的非继承注释不再存在于被覆盖的方法中。一旦另一个基于注释的 API 处理了您的 bean,所有注释都会消失,这会导致您的结果。这适用于所有类型的注释。关于类型、方法和方法参数的那些。

但这可以避免吗?最肯定的是使用代理生成器that was written recently and is built with knowledge of what annotations are,这对于在 Java 虚拟机早期首次发布的 cglib 来说是不正确的。但是,只要 Spring 不脱离 cglib,您就必须忍受今天的限制。

【讨论】:

  • 我不确定 CGLIB 是否是导致此问题的原因。这个问题不会发生在以某种方式注释的方法上,而是发生在代理方法中使用的带有注释的对象上。 Spring AOP 代理逻辑在处理 aop 切入点时与 aspectj 进行代码共享。所以我的想法是,这会导致方面解析子系统在 spring-context 的 real-aspectj 部分生效之前检测/加载类。我想,我在某个地方得到了一些信息,即必须确保 aspectj-aspects 必须比其他加载更多才能“检测”新的编织类。
猜你喜欢
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 2015-04-20
相关资源
最近更新 更多