1

请考虑使用 spring 4.0.7 的以下情况

对于 Eclipselink,我们使用 load-time-weaver。因此,我们想同时使用 @EnableSpringConfigured 和 @EnableLoadTimeWeaving 来试验 Springs @Configurable 注解。

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

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

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

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

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

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

提前致谢!

4

1 回答 1

1

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

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

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

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

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

但这是可以避免的吗?最肯定的是使用最近编写的代理生成器,它是在了解注释是什么的情况下构建的,这对于在 Java 虚拟机早期首次发布的 cglib 来说是不正确的。但是,只要 Spring 不脱离 cglib,您就必须忍受今天的限制。

于 2014-09-17T08:32:25.407 回答