我尝试调试原因,发现两个MappingJackson2HttpMessageConverters的生产顺序。
首先,在 中org.springframework.boot.autoconfigure.web.JacksonHttpMessageConvertersConfiguration
,该mappingJackson2HttpMessageConverter
方法创建一个新容器MappingJackson2HttpMessageConverter
并注册到 Spring 容器。
@Configuration
class JacksonHttpMessageConvertersConfiguration {
@Configuration
@ConditionalOnClass(ObjectMapper.class)
@ConditionalOnBean(ObjectMapper.class)
@ConditionalOnProperty(name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY, havingValue = "jackson", matchIfMissing = true)
protected static class MappingJackson2HttpMessageConverterConfiguration {
@Bean
@ConditionalOnMissingBean(value = MappingJackson2HttpMessageConverter.class, ignoredType = {
"org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter",
"org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter" })
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(
ObjectMapper objectMapper) {
return new MappingJackson2HttpMessageConverter(objectMapper);
}
}
//......
}
其次,在 中org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration
,该messageConverters
方法创建一个HttpMessageConverters
对象。
@Configuration
@ConditionalOnClass(HttpMessageConverter.class)
@AutoConfigureAfter({ GsonAutoConfiguration.class, JacksonAutoConfiguration.class })
@Import({ JacksonHttpMessageConvertersConfiguration.class,
GsonHttpMessageConvertersConfiguration.class })
public class HttpMessageConvertersAutoConfiguration {
//......
@Bean
@ConditionalOnMissingBean
public HttpMessageConverters messageConverters() {
return new HttpMessageConverters((this.converters != null) ? this.converters
: Collections.<HttpMessageConverter<?>>emptyList());
}
//......
}
构造函数参数 this.converters 有一个StringHttpMessageConverter
对象和最后一个MappingJackson2HttpMessageConverter
对象。
第三,在org.springframework.boot.autoconfigure.web.HttpMessageConverters
构造函数中,执行getDefaultConverters
方法得到一个具有新StringHttpMessageConverter
对象和新MappingJackson2HttpMessageConverter
对象的List。并且getCombinedConverters
不删除重复的对象。
public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>> {
public HttpMessageConverters(boolean addDefaultConverters,
Collection<HttpMessageConverter<?>> converters) {
List<HttpMessageConverter<?>> combined = getCombinedConverters(converters,
addDefaultConverters ? getDefaultConverters()
: Collections.<HttpMessageConverter<?>>emptyList());
combined = postProcessConverters(combined);
this.converters = Collections.unmodifiableList(combined);
}
}
我想问题可能出在这个getCombinedConverters
方法上。
private List<HttpMessageConverter<?>> getCombinedConverters(
Collection<HttpMessageConverter<?>> converters,
List<HttpMessageConverter<?>> defaultConverters) {
List<HttpMessageConverter<?>> combined = new ArrayList<HttpMessageConverter<?>>();
List<HttpMessageConverter<?>> processing = new ArrayList<HttpMessageConverter<?>>(
converters);
for (HttpMessageConverter<?> defaultConverter : defaultConverters) {
Iterator<HttpMessageConverter<?>> iterator = processing.iterator();
while (iterator.hasNext()) {
HttpMessageConverter<?> candidate = iterator.next();
if (isReplacement(defaultConverter, candidate)) {
combined.add(candidate);
iterator.remove();
}
}
combined.add(defaultConverter);
if (defaultConverter instanceof AllEncompassingFormHttpMessageConverter) {
configurePartConverters(
(AllEncompassingFormHttpMessageConverter) defaultConverter,
converters);
}
}
combined.addAll(0, processing);
return combined;
}
该方法使用isReplacement
双循环的方法来检查重复的对象。但代码不会删除重复的对象。对于重复对象,首先与现有转换器合并,然后添加重复的默认转换器对象。