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
    }
}
19
demandé sur Markus 2014-06-18 17:35:31

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 UserRepositoryUserDetailsService

7
répondu Jakub Kubrynski 2014-06-18 22:30:29

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.

5
répondu Markus 2014-06-19 08:55:39