如何强制执行弹簧配置类的加载顺序?

2022-09-02 01:52:02

我正在一个多模块项目(maven)上使用spring-boot。每个模块都有自己的@Configuration类。基本上我有以下布局

Module foo-embedded (run just call the SpringApplication.run()) 方法:

@Configuration
@EnableAutoConfiguration
@ComponentScan("de.foobar.rootpackage")
@Import({ApplicationConfig.class, RepositoryConfig.class, SecurityConfig.class})
public class FooApplication {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(FooApplication.class, args);
    }
}

模块 foo-common(包含所有 bean 和 spring-data-jpa 初始化配置)

@Configuration
@EnableJpaRepositories
@EnableTransactionManagement(entityManagerFactoryRef="entityManagerFactory")
public class RepositoryConfig {

    @Bean(destroyMethod = "shutdown")
    public DataSource getDataSource() {
        // returning a Hikari CP here
    }

    @Bean(name = "entityManagerFactory") // overriding spring boots default
    public EntityManagerFactory getEntityManagerFactory() {
        // returning a new LocalEntityManagerFactoryBean here
    }
}

模块 foo-security(包含 spring-securiy 配置和相关域类),它对 foo-common 具有 maven 依赖性

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // configuring HTTP security and defining my UserDetailsService Bean
}

当我使用 FooApplication 类启动应用程序时,一切都按预期工作。上面提到的UserDetailsServiceImpl get的自动连接到我的UserRepository,它是通过@EnableJpaRepositories注释创建的。

由于我想编写一些集成测试,因此我已将测试 clss 添加到我的一个模块中。

模块 foo-media(包含一些与域相关的东西以及该模块的测试用例)

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {RepositoryConfig.class, SecurityConfig.class})
@WebAppConfiguration
@IntegrationTest
public class DirectoryIntegrationTest {
    // my test code
}

当我运行测试时,似乎安全配置在存储库配置之前加载.class确实如此。由于安全配置定义了必须自动连接的用户服务Impl,因此测试无法从

NoSuchBeanDefinitionException telling me: No qualifying bean of type [com.foo.rootpackage.security.repository.UserRepository]

我已经尝试在豆的定义中添加,告诉我春天找不到这个名字的豆子。@DependsOn("UserRepository")UserDetailsService

任何提示或帮助将不胜感激!提前致谢!

---- 编辑(因为我被要求提供更多代码)----

对于测试,我不使用实际的 RepositoryConfig.class,但在通用模块中有一个 TestRepositoryConfig.class。看起来像这样

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory", basePackages = "de.foobar.rootpackage")
public class TestRepositoryConfig extends RepositoryConfig {

    @Bean
    @Override
    public DataSource getDataSource() {
        // returning the ds for testing
    }
}

答案 1

您可以在配置类上使用注释来定义负载排序。但这很奇怪,因为春天应该解决正确的顺序 - 所以请检查你的财产注入@OrderUserRepositoryUserDetailsService


答案 2

所以我能够解决这个问题。正如它所指出的,它与配置类的加载顺序无关(这是我的第一个想法)。

您可能会注意到,唯一具有注释的配置是FooApplication.class Spring无法找到存储库,因为它不知道在哪里查找。提供 basePackages 属性,如下所示:@ComponentScan

@EnableJpaRepositories(basePackages = "de.foobar.rootpackage")

在TestRepositoryConfig.class在这里做了这个把戏。


推荐