【问题标题】:Does ComponentScan order matter?ComponentScan 顺序重要吗?
【发布时间】:2014-08-06 15:20:08
【问题描述】:

我正在使用注释设置一个非常小的带有 Boot 的 Spring/REST/JPA 项目。

当我将 JPA 存储库类移到不同的包并在其包上调用 componentscan 时,我在具有 Autowired 存储库变量的 REST 控制器类中遇到了一些 Bean not found 错误。但是,当我的所有文件(共 5 个)都在同一个包中时,一切正常。

所以我想知道,尽管不太可能,组件扫描顺序是否重要?例如,如果一个类正在 AutoWiring 来自尚未“组件扫描”的包中的一些 bean,这会导致 Bean not found 错误吗?

【问题讨论】:

  • 没有。 Spring 加载所有 bean,然后进行布线。

标签: spring spring-data spring-data-jpa spring-boot


【解决方案1】:

不,Spring 会在适当的时候从文件和注释以及环境中加载所有配置信息。然后它根据它在内存中计算的依赖树创建bean(类的实例)。为了做到这一点,它必须在启动时对整个配置有一个很好的了解。从所有聚合配置信息派生的整个模型称为应用程序上下文。

在 Spring 的现代版本中,应用程序上下文在运行时是灵活的,因此并非所有配置都必须预先知道,但灵活的配置范围有限,必须仔细规划。

【讨论】:

【解决方案2】:

在结构良好的程序中不会,因为首先每个 bean 都会被实例化,然后自动装配,然后您就可以实际使用它们了。

但是,在某些情况下,订单确实很重要,我无法弄清楚发生了什么。所以这是一个重要的例子:

  1. 您有一些要填充数据的存储库,将其称为 SetupData 组件。
  2. 然后使用@PostConstruct 保存默认对象。
  3. 您有一些此存储库依赖但不受 Spring 管理的组件,例如 @Converter。
  4. @Converter 依赖于您将静态注入的其他一些组件。

在这种情况下,@PostConstruct 方法将在您的 @Converter 中的组件自动装配之前执行,这将导致异常。

依赖 ComponentScan 顺序是一个坏习惯,因为它不直观,尤其是当您与可能不知道的多人一起工作时。或者可能存在这样的依赖关系,您无法通过更改扫描顺序来修复代码。

在这种情况下,最好的解决方案是使用负责运行初始化函数的任务执行器服务。

【讨论】:

    【解决方案3】:

    可能有几个问题:

    • 您将您的课程移出某个包,在该包中您拥有不带参数的 @ComponentScan。这基本上意味着组件仅在此包及其子包中被扫描。因此,移动的类不会被扫描,也没有要连接的 bean。
    • @ComponentScan 参数中的包名称错误。

    顺序根本不重要。有一个@Order 注释,但它的目的更多是关于以不同的顺序加载 sth 的多个实现。 首先创建 Bean 定义,它们与布线无关。然后通过 bean 后处理器,注入自动装配的 bean。由于没有bean定义。没有什么可以注射的。

    【讨论】:

      【解决方案4】:

      也许您需要分享一些代码。当你移动这些东西时,你还需要告诉 Spring 它们去了哪里。我的猜测是你还没有定义@EntityScan@EnableJpaRepositories(默认为@EnableAutoConfiguration 的位置)。

      【讨论】:

        猜你喜欢
        • 2018-01-09
        • 1970-01-01
        • 1970-01-01
        • 2017-11-18
        • 2012-06-27
        • 2010-09-07
        • 1970-01-01
        • 2016-10-24
        相关资源
        最近更新 更多