¿Debo anotar la clase de configuración como @Configuration para realizar pruebas?
-
21-12-2019 - |
Pregunta
Pasé algún tiempo resolviendo el problema de falta org.joda.time.DateTime->java.util.Date
convertidor en Spring Data (que debería estar habilitado de forma predeterminada cuando Joda-Time está en una ruta de clase).Encontré una razón, pero generó una pregunta sobre @Configuration
anotación en primavera.
Configuración de aplicación estándar usando AbstractMongoConfiguration
de datos de primavera-mongodb:
@Configuration
@ComponentScan
@EnableMongoRepositories
public class AppConfig extends AbstractMongoConfiguration { ... }
Una prueba que usa explícitamente la clase AppConfig (con Spock, pero se usan mecanismos internos proporcionados por Spring-test):
@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
}
}
Funciona bien.Pero cuando la anotación @Configuration en AppConfig es remoto/comentó:
//@Configuration
@ComponentScan
@EnableMongoRepositories
public class AppConfig extends AbstractMongoConfiguration { ... }
la prueba falla con:
org.springframework.core.convert.ConverterNotFoundException:
No converter found capable of converting from type org.joda.time.DateTime to type java.util.Date
AFAIK no es necesario usarlo @Configuration
para la clase de configuración cuando está registrada explícitamente en el contexto (por clases en @ContextConfiguration
o un register()
método en AnnotationConfigWebApplicationContext
).Las clases se procesan de todos modos y se encuentran todos los beans declarados.A veces es útil no utilizar @Configuration
para evitar que un escaneo de componentes detecte cuando hay 2 clases de configuración similares en los mismos paquetes en un contexto de prueba utilizado por diferentes pruebas.
Por lo tanto, creo que podría haber un error en Spring que causa diferentes procesamientos internos de beans en el contexto dependiendo del uso o no. @Configuration
anotación.Comparé los registros de Spring de estos dos casos y hay algunas diferencias, pero no puedo determinar a qué se deben en las clases internas de Spring.Antes de enviar un error, me gustaría preguntar:
Mi pregunta. ¿Hay alguna razón explicable por la cual Spring para la misma clase de configuración (señalada explícitamente en @ContextConfiguration
) utiliza (o no) convertidores para Joda-Time dependiendo de la existencia de un @Configuration
¿anotación?
Creé también un proyecto de inicio rápido reproduciendo el tema.spring-data-mongodb 1.3.3, primavera 4.0.0, joda-time 2.3.
Solución
Todo está bien en este comportamiento. AbstractMongoConfiguration
está anotado por @Configuration
, pero de hecho esta anotación no es @Inherited
, por lo que debes anotar explícitamente tu clase.
cuando quitas @Configuration
anotación entonces tu AppConfig
la clase no es una lleno configuración.Sus procesos como ligero configuración sólo porque contiene métodos anotados por @Bean
- consulte los métodos en org.springframework.context.annotation.ConfigurationClassUtils
isFullConfigurationCandidate()
isLiteConfigurationCandidate()
isFullConfigurationClass()
Finalmente solo lleno (anotado por @Configuration
) las clases de configuración son procesos y se mejoran mediante postprocesadores de configuración; mire ConfigurationClassPostProcessor.enhanceConfigurationClasses()