マルチモジュールプロジェクト(maven)でspring-bootを使用しています。各モジュールには、独自の@Configurationクラスがあります。基本的に私は次のレイアウトを持っています
モジュールfoo-embedded(実行は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-commonへのMaven依存関係を持つモジュールfoo-security(spring-securiy構成と関連ドメインクラスを含む)
_@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// configuring HTTP security and defining my UserDetailsService Bean
}
_
FooApplicationクラスを使用してアプリケーションを起動すると、すべてが期待どおりに機能します。上記のUserDetailsServiceImplは、@ EnableJpaRepositoriesアノテーションを介して作成されているUserRepositoryと自動接続されます。
いくつかの統合テストを書きたいので、モジュールの1つにテストクラスを追加しました。
モジュールfoo-media(ドメイン関連のものとそのモジュールのテストケースを含む)
_@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {RepositoryConfig.class, SecurityConfig.class})
@WebAppConfiguration
@IntegrationTest
public class DirectoryIntegrationTest {
// my test code
}
_
テストを実行すると、RepositoryConfig.classが実行される前にSecurityConfigurationがロードされるようです。セキュリティ構成は、自動配線する必要があるUserServiceImplを定義しているため、テストは、
_NoSuchBeanDefinitionException telling me: No qualifying bean of type [com.foo.rootpackage.security.repository.UserRepository]
_
UserDetailsService
のBean定義に@DependsOn("UserRepository")
を追加しようとしましたが、その名前ではSpringがBeanを見つけられないことを教えてくれました。
ヒントやヘルプは大歓迎です!前もって感謝します!
---- [〜#〜] edit [〜#〜](コードの追加を求められたため)----
テストでは、実際の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
}
}
_
だから私はこれを解決することができました。それが指摘したように、それは構成クラスのロード順序とは何の関係もありませんでした(これは私の最初の考えでした)。
お気づきかもしれませんが、@ComponentScan
アノテーションは、FooApplication.classであり、Springはリポジトリを見つけることができませんでした。どこを探すべきかわからなかったためです。次のようにbasePackages属性を提供します。
@EnableJpaRepositories(basePackages = "de.foobar.rootpackage")
testRepositoryConfig.classでこのトリックを行いました。
構成クラスで@Order
注釈を使用して、ロード順序を定義できます。しかし、Springは適切な順序を解決する必要があるため、奇妙です。したがって、UserRepository
in UserDetailsService