Виновник здесь, на HttpMessageConverters
public HttpMessageConverters(boolean addDefaultConverters,
Collection<HttpMessageConverter<?>> converters) {
List<HttpMessageConverter<?>> combined = getCombinedConverters(converters,
addDefaultConverters ? getDefaultConverters() : Collections.emptyList());
combined = postProcessConverters(combined);
this.converters = Collections.unmodifiableList(combined);
}
В частности, эта строка (отформатированная)
List<HttpMessageConverter<?>> combined =
getCombinedConverters(
converters,
addDefaultConverters
? getDefaultConverters()
: Collections.emptyList());
Коллекция converters
содержит отсканированные HttpMessageConverter
(s).
В зависимости от среды.
Этот список затем объединяется с по умолчанию , предоставленным WebMvcConfigurationSupport
public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
private static final boolean romePresent;
private static final boolean jaxb2Present;
private static final boolean jackson2Present;
private static final boolean jackson2XmlPresent;
private static final boolean jackson2SmilePresent;
private static final boolean jackson2CborPresent;
private static final boolean gsonPresent;
private static final boolean jsonbPresent;
...
Infact документация для WebMvcConfigurationSupport
состояний
Этот класс регистрируется ...
... диапазон HttpMessageConverters
в зависимости от сторонних библиотек, доступных на пути к классам.
Сканированные HttpMessageConverter
найдены и созданы с помощью HttpMessageConvertersAutoConfiguration
, документация которых
Автоконфигурация для HttpMessageConverters
.
Этот класс представляет собой StringHttpMessageConverter
@Bean
@ConditionalOnMissingBean
public StringHttpMessageConverter stringHttpMessageConverter() {
StringHttpMessageConverter converter = new StringHttpMessageConverter(
this.properties.getCharset());
converter.setWriteAcceptCharset(false);
return converter;
}
Чем импортируются автоконфигурации Джексона или Гсона
@Import({
JacksonHttpMessageConvertersConfiguration.class
GsonHttpMessageConvertersConfiguration.class,
JsonbHttpMessageConvertersConfiguration.class
})
И вот как эти основанные на окружающей среде "суммируются" с предопределенными.
Spring не смущает дубликаты, потому что он просто берет первое, которое совместимо.
Посмотрите, как выбирается HttpMessageConverter
Вы можете видеть, что это просто цикл for, и каждого конверта просят сказать "я могу это сделать?" по методу canWrite
Первый действительный выбран.