【问题标题】:Alternative to Spring's @Configurable for performance reasons?出于性能原因,替代 Spring 的 @Configurable?
【发布时间】:2013-03-29 13:20:00
【问题描述】:

我在一段必须高性能的代码中为非托管 spring 实例使用 @Configurable bean。我们在 new 运算符中使用了很多非托管 bean,在我们的分析中我们注意到 @Configurable 注解的使用大大降低了速度。

对于这个特定的部分,我们想要一种更快的从上下文中提取 bean 的方法(只是一个直接的 applicationContext.getBean())。我知道我们放弃了 IoC 这样做,但这是一种特殊情况,而不是正常模式。

我们使用 CTW 进行编织,但我想知道 spring 在幕后使用什么机制来获取应用程序上下文,以便我们可以简单地抓取它并使用 getBean?静态应用程序上下文?它是否存储在 threadlocal 的某个地方?

【问题讨论】:

  • 这个问题对我来说没有多大意义。 Spring 文档描述了 @Configurable 是如何实现的(参见 3.1 参考的第 8.8.1 节),它们还描述了如何访问应用程序上下文。但是,真的,您认为getBean() 会让您的生活更轻松吗?如果您准确描述您使用@Configurable 做什么,您的问题会更好(并且更有可能得到有用的答案),因为可能有更好的解决方案。
  • 看看 Apache Wicket 模块 wicket-ioc 是如何处理依赖注入的。他们的方法非常适用于非托管 bean,并且出于性能原因结合了缓存机制。我已经创建了他们模块的独立版本,因此它可以在任何地方用作@Configurable 替代方案 - github.com/sabomichal/spring-injector

标签: java spring configurable aspect


【解决方案1】:

方面是由 AspectJ 管理的单例。当您将切面放入 Spring 配置文件时,Spring 实际上并没有创建切面。相反,它使用aspectOf() 获取对方面的引用。

这意味着(在您进行编织时的编译时)您的@Configurable 注解被挂钩到单例AnnotationBeanConfigurerAspect。然后,当您加载应用程序上下文时,Spring 会获得对同一个单例切面的引用,并在切面上调用setBeanFactory() 方法(因为它实现了BeanFactoryAware)。

这个魔法当然会带来麻烦。如果您有两个应用程序上下文,那么第二个会覆盖第一个的配置,这可能会非常混乱。

要直接回答您的问题,这意味着您所要做的就是创建一个实现BeanFactoryAware 的新方面(这里是AnnotationBeanConfigurerAspect 的代码,您可以将其用作示例),然后“实例化”它在你的 spring 配置文件中,你的方面现在可以访问 bean 工厂。

如果您要追求性能,请注意,上述内容并不比创建对BeanFactory 的静态引用并在启动应用程序时实例化它更干净,因此您不妨照原样执行静态引用更简单。

【讨论】:

  • 我们最终使用了一个 spring 托管 bean 的静态引用,其中注入了依赖项,性能要好得多,谢谢。
猜你喜欢
  • 1970-01-01
  • 2021-05-07
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-30
  • 1970-01-01
  • 2010-11-16
相关资源
最近更新 更多