Comment appliquer l'ordre de chargement des classes de configuration des ressorts?
je travaille avec spring-boot sur un projet multi-modules (maven). Chaque module a sa propre classe @Configuration. Fondamentalement, j'ai la disposition suivante
Module foo-embedded (fonctionne appelle la SpringApplication.run()) méthode:
@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);
}
}
Module foo-commune (contient tous les haricots et spring-data-jpa l'initialisation de la config)
@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
}
}
Module foo-security (contenant la configuration spring-securiy et les classes de domaines associées), qui a un maven dépendance à l'égard de foo-common
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// configuring HTTP security and defining my UserDetailsService Bean
}
quand je démarre l'application en utilisant la classe FooApplication, tout fonctionne comme prévu. L'userdetailsserviceimpl get's autowired avec my UserRepository qui est créé par l'annotation @EnableJpaRepositories.
depuis que je veux écrire quelques tests d'intégration, j'ai ajouté un test clss à l'un de mes modules.
Module foo-media (contenant des éléments relatifs au domaine ainsi que des cas d'essai pour ces éléments) module)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {RepositoryConfig.class, SecurityConfig.class})
@WebAppConfiguration
@IntegrationTest
public class DirectoryIntegrationTest {
// my test code
}
quand j'exécute le test, il semble que la configuration de sécurité soit chargée avant la configuration de RepositoryConfig.classe. Puisque la config de sécurité a défini le UserServiceImpl qui doit être autowired, le test ne démarre pas avec un
NoSuchBeanDefinitionException telling me: No qualifying bean of type [com.foo.rootpackage.security.repository.UserRepository]
j'ai déjà essayé d'ajouter @DependsOn("UserRepository")
à la fève définition de UserDetailsService
, me disent que le printemps ne peut pas trouver un haricot de ce nom.
toute suggestion ou aide serait grandement appréciée! Merci à l'avance!
- - - - EDIT (puisqu'on m'a demandé de fournir plus de code) ----
Pour les tests je n'utilise pas le réel RepositoryConfig.classe, mais avoir un TestRepositoryConfig.classe dans le module commun. À la recherche comme ceci
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory", basePackages = "de.foobar.rootpackage")
public class TestRepositoryConfig extends RepositoryConfig {
@Bean
@Override
public DataSource getDataSource() {
// returning the ds for testing
}
}
2 réponses
Vous pouvez utiliser @Order
annotation sur vos classes de configuration pour définir l'ordre de charge. Mais c'est étrange parce que le ressort devrait résoudre l'ordre approprié - donc s'il Vous Plaît vérifier si votre propriété injecter UserRepository
UserDetailsService
j'ai Donc été en mesure de résoudre ce problème. Comme il l'a souligné, cela n'avait rien à voir avec l'ordre de chargement des classes de configuration (ce qui était ma première pensée).
Comme vous pouvez le remarquer, la seule Configuration qui avait un @ComponentScan
l'annotation était la FooApplication.classe
Spring n'a pas pu trouver les dépôts car il ne savait pas où chercher. Fournir l'attribut basePackages comme ceci:
@EnableJpaRepositories(basePackages = "de.foobar.rootpackage")
au Testiprepositoryconfig.la classe a fait le tour ici.