Dois-je annoter la classe de configuration comme @Configuration pour les tests ?
-
21-12-2019 - |
Question
J'ai passé du temps à résoudre le problème des disparitions org.joda.time.DateTime->java.util.Date
convertisseur dans Spring Data (qui devrait être activé par défaut lorsque Joda-Time est sur un chemin de classe).J'ai trouvé une raison, mais cela a généré une question sur @Configuration
annotation au printemps.
Configuration d'application standard utilisant AbstractMongoConfiguration
de spring-data-mongodb :
@Configuration
@ComponentScan
@EnableMongoRepositories
public class AppConfig extends AbstractMongoConfiguration { ... }
Un test qui utilise explicitement la classe AppConfig (avec Spock, mais les mécanismes internes fournis par spring-test sont utilisés) :
@ContextConfiguration(classes = AppConfig)
class JodaDocRepositorySpec extends Specification {
@Autowired
private JodaDocRepository jodaDocRepository
def "save document with DateTime"() {
given:
def jodaDoc = new JodaDoc(DateTime.now())
when:
def savedJodaDoc = jodaDocRepository.save(jodaDoc)
then:
savedJodaDoc.id
}
}
Ça fonctionne bien.Mais lorsque l'annotation @Configuration dans AppConfig est supprimé/ commenté :
//@Configuration
@ComponentScan
@EnableMongoRepositories
public class AppConfig extends AbstractMongoConfiguration { ... }
le test échoue avec :
org.springframework.core.convert.ConverterNotFoundException:
No converter found capable of converting from type org.joda.time.DateTime to type java.util.Date
AFAIK, il n'est pas nécessaire de l'utiliser @Configuration
pour la classe de configuration lorsqu'elle est explicitement enregistrée dans le contexte (par les classes en @ContextConfiguration
ou un register()
méthode dans AnnotationConfigWebApplicationContext
).Les classes sont quand même traitées et tous les beans déclarés sont trouvés.Il est parfois utile de ne pas utiliser @Configuration
pour empêcher la détection par une analyse de composants lorsqu'il existe 2 classes de configuration similaires dans les mêmes packages dans un contexte de test utilisé par différents tests.
Par conséquent, je pense qu'il pourrait y avoir un bug au printemps qui entraîne un traitement différent des beans internes dans le contexte en fonction d'une utilisation ou non. @Configuration
annotation.J'ai comparé les journaux Spring de ces deux cas et il existe quelques différences, mais je ne suis pas en mesure de déterminer de quoi sont-ils causés dans les classes internes de Spring.Avant de soumettre un bug, je voudrais demander :
Ma question. Y a-t-il une raison explicable pour laquelle Spring pour la même classe de configuration (indiqué explicitement dans @ContextConfiguration
) utilise (ou non) des convertisseurs pour Joda-Time selon l'existence d'un @Configuration
annotation?
J'ai également créé un projet de démarrage rapide reproduisant le problème.spring-data-mongodb 1.3.3, spring 4.0.0, joda-time 2.3.
La solution
Tout va bien dans ce comportement. AbstractMongoConfiguration
est annoté par @Configuration
, mais en fait cette annotation n'est pas @Inherited
, vous devez donc annoter explicitement votre classe.
Lorsque vous supprimez @Configuration
annotation alors votre AppConfig
la classe n'est pas un complet configuration.Ce sont des processus en tant que léger configuration simplement parce qu'elle contient des méthodes annotées par @Bean
- veuillez vous référer aux méthodes dans org.springframework.context.annotation.ConfigurationClassUtils
isFullConfigurationCandidate()
isLiteConfigurationCandidate()
isFullConfigurationClass()
Enfin seulement complet (annoté par @Configuration
) les classes de configuration sont des processus et améliorées par des post-processeurs de configuration - regardez ConfigurationClassPostProcessor.enhanceConfigurationClasses()