Spring Boot 根据外部依赖自动配置顺序

Tam*_*agó 7 java spring jar spring-boot

我在尝试让自动配置正常工作时遇到问题。我有两个 jar,如下所示,每个都有一个 spring.factories 文件,其中为 EnableAutoConfigurationProperties 启用了这两个文件。

这个配置在my-package-mock.jar中,它依赖于下面的my-package-real.jar:

package org.packages.package.packageA;
@Configuration
@AutoConfigureBefore(AutoConfigurationB.class)
public class AutoConfigurationA {

    @Bean
    public MyService mockService() {
        return new MyMockService();
    }
}
Run Code Online (Sandbox Code Playgroud)

此配置位于 my-package-real.jar 中:

package org.packages.package.packageB;
@Configuration
@ConditionalOnMissingBean(MyService.class)
public class AutoConfigurationB {

    @Bean
    public MyService realService() {
        return new MyRealService();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在的想法是,如果包含 my-package-mock.jar,则 AutoConfigurationB 将不会被处理,因为 A 被排序在之前,并且当它到达 B 时,MyService 已经定义了。但是,在包含这些 jar 的第三个项目中使用时它不起作用。从类路径加载这些 jar 时,看起来 AutoConfigureOrder 注释被跳过,并且这些配置按照 jvm 加载这些类的顺序进行处理。在我的特定情况下,它首先执行 B,此时 MyService 尚未定义,因此将实例化 RealService bean。我怎样才能让它发挥作用?

显然这是一个小例子,其中模拟上的 @Primary 注释可以完成这项工作,但这不是我想要的。

编辑:看来如果 @SpringBootApplication 注释的 main 不是这些配置所在的包的一部分,那么事情就可以工作了。例如,注释不在“org.packages.package”中,而是在“org.somewhereelse”中,那么事情就可以了。

package org.packages.package;

@SpringBootApplication
public class TestApplication {

    public static void main(String[] args) throws Exception {
    SpringApplication.run(Collections.singletonList(TestApplication.class).toArray(), args);
    }
}
Run Code Online (Sandbox Code Playgroud)

And*_*son 7

@AutoConfigureBefore并且@AutoConfigureAfter仅在由于启用自动配置而加载配置类并在 中列出时应用spring.factories。当您的自动配置类位于org.packages.package(或子包)中并且您的主应用程序类位于同一包中时,Spring Framework 的标准组件扫描会找到它们。发生这种情况是因为@SpringBootApplication启用了对其所注释的类的包的组件扫描。因此,自动配置特定的排序不适用。

为了避免这个问题,您应该将自动配置类放在任何应用程序代码都不使用的包中。