Должен ли я аннотировать класс конфигурации как @Configuration для тестирования?
-
21-12-2019 - |
Вопрос
Я потратил некоторое время на решение проблемы с отсутствием org.joda.time.DateTime->java.util.Date
конвертер в Spring Data (который должен быть включен по умолчанию, когда Joda-Time находится в пути к классам).Я нашел причину, но она породила вопрос о @Configuration
аннотация весной.
Стандартная конфигурация приложения с использованием AbstractMongoConfiguration
из весенних данных-mongodb:
@Configuration
@ComponentScan
@EnableMongoRepositories
public class AppConfig extends AbstractMongoConfiguration { ... }
Тест, который явно использует класс AppConfig (со Spock, но внутри используются механизмы, предоставляемые 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
}
}
Он работает нормально.Но когда аннотация @Configuration в AppConfig удаленный/прокомментировал:
//@Configuration
@ComponentScan
@EnableMongoRepositories
public class AppConfig extends AbstractMongoConfiguration { ... }
тест не пройден с:
org.springframework.core.convert.ConverterNotFoundException:
No converter found capable of converting from type org.joda.time.DateTime to type java.util.Date
AFAIK не нужно использовать @Configuration
для класса конфигурации, если он явно зарегистрирован в контексте (классами в @ContextConfiguration
или register()
метод в AnnotationConfigWebApplicationContext
).Классы в любом случае обрабатываются, и все объявленные компоненты находятся.Иногда полезно не использовать @Configuration
чтобы предотвратить обнаружение при сканировании компонентов двух аналогичных классов конфигурации в одних и тех же пакетах в тестовом контексте, используемом разными тестами.
Поэтому я думаю, что это может быть ошибка в Spring, которая приводит к различной внутренней обработке bean-компонентов в контексте в зависимости от использования или нет. @Configuration
аннотация.Я сравнил журналы Spring этих двух случаев и обнаружил некоторые различия, но не смог определить, чем они вызваны во внутренних классах Spring.Прежде чем сообщить об ошибке, я хотел бы спросить:
Мой вопрос. Есть ли объяснимая причина, по которой Spring для одного и того же класса конфигурации (явно указано в @ContextConfiguration
) использует (или нет) конвертеры для Joda-Time в зависимости от существования @Configuration
аннотация?
Я также создал проект быстрого старта воспроизводя проблему.весна-данные-mongodb 1.3.3, весна 4.0.0, время йода 2.3.
Решение
В таком поведении все в порядке. AbstractMongoConfiguration
аннотировано @Configuration
, но на самом деле этой аннотации нет @Inherited
, поэтому вам необходимо явно аннотировать свой класс.
Когда вы удалите @Configuration
аннотация, то ваша AppConfig
класс не является полный конфигурация.Это процессы как облегченный конфигурации только потому, что она содержит методы, аннотированные @Bean
- пожалуйста, обратитесь к методам в org.springframework.context.annotation.ConfigurationClassUtils
isFullConfigurationCandidate()
isLiteConfigurationCandidate()
isFullConfigurationClass()
Наконец только полный (с аннотацией @Configuration
) классы конфигурации являются процессами и расширяются постпроцессорами конфигурации - посмотрите ConfigurationClassPostProcessor.enhanceConfigurationClasses()