Bootstrap

SpringBoot源码阅读(9)——转换服务

SpringBoot中加载转换服务的入口是SpringApplication实例方法prepareEnvironment,第341行。

configureEnvironment(environment, applicationArguments.getSourceArgs());
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
	if (this.addConversionService) {
		environment.setConversionService(new ApplicationConversionService());
	}
	configurePropertySources(environment, args);
	configureProfiles(environment, args);
}

注释:

按照该顺序委托给configurePropertySources(ConfigurationEnvironment,String[])和configureProfiles(ConfigurationEnvironment,String]])的模板方法。覆盖此方法以完全控制环境自定义,或者覆盖以上方法之一以分别对属性源或配置文件进行细粒度控制。

addConversionService 默认为true,则创建ApplicationConversionService

ApplicationConversionService

父类:FormattingConversionServicec,爷爷类:GenericConversionService
现接口:FormatterRegistry EmbeddedValueResolverAware ConverterRegistry ``EmbeddedValueResolverAware Aware

主要方法

private ApplicationConversionService(StringValueResolver embeddedValueResolver, boolean unmodifiable) {
	if (embeddedValueResolver != null) {
		setEmbeddedValueResolver(embeddedValueResolver);
	}
	configure(this);
	this.unmodifiable = unmodifiable;
}
public static void configure(FormatterRegistry registry) {
	DefaultConversionService.addDefaultConverters(registry);
	DefaultFormattingConversionService.addDefaultFormatters(registry);
	addApplicationFormatters(registry);
	addApplicationConverters(registry);
}

加转换器的主要方法:addPrinter addParser addFormatter addFormatterForFieldType addConverter addFormatterForFieldType addFormatterForFieldAnnotation addConverter addConverterFactory

添加的转换器工厂

org.springframework.core.convert.support.NumberToNumberConverterFactory
org.springframework.core.convert.support.StringToNumberConverterFactory
org.springframework.core.convert.support.CharacterToNumberFactory

org.springframework.core.convert.support.StringToEnumConverterFactory
org.springframework.core.convert.support.IntegerToEnumConverterFactory

添加的转换器

org.springframework.core.convert.support.ObjectToStringConverter
org.springframework.core.convert.support.StringToCharacterConverter
org.springframework.core.convert.support.NumberToCharacterConverter
org.springframework.core.convert.support.StringToBooleanConverter
org.springframework.core.convert.support.EnumToStringConverter
org.springframework.core.convert.support.EnumToIntegerConverter
org.springframework.core.convert.support.StringToLocaleConverter
org.springframework.core.convert.support.StringToCharsetConverter
org.springframework.core.convert.support.StringToCurrencyConverter
org.springframework.core.convert.support.StringToPropertiesConverter
org.springframework.core.convert.support.StringToUUIDConverter
org.springframework.core.convert.support.PropertiesToStringConverter

集合类转换器

org.springframework.core.convert.support.ArrayToCollectionConverter
org.springframework.core.convert.support.CollectionToArrayConverter
org.springframework.core.convert.support.ArrayToArrayConverter
org.springframework.core.convert.support.CollectionToCollectionConverter
org.springframework.core.convert.support.MapToMapConverter
org.springframework.core.convert.support.ArrayToStringConverter
org.springframework.core.convert.support.StringToArrayConverter
org.springframework.core.convert.support.ArrayToObjectConverter
org.springframework.core.convert.support.ObjectToArrayConverter
org.springframework.core.convert.support.CollectionToStringConverter
org.springframework.core.convert.support.StringToCollectionConverter
org.springframework.core.convert.support.CollectionToObjectConverter
org.springframework.core.convert.support.ObjectToCollectionConverter
org.springframework.core.convert.support.StreamConverter

其他转换器

org.springframework.core.convert.support.ByteBufferConverter
org.springframework.core.convert.support.StringToTimeZoneConverter
org.springframework.core.convert.support.ZoneIdToTimeZoneConverter
org.springframework.core.convert.support.ZonedDateTimeToCalendarConverter
org.springframework.core.convert.support.ObjectToObjectConverter
org.springframework.core.convert.support.IdToEntityConverter
org.springframework.core.convert.support.FallbackObjectToStringConverter
org.springframework.core.convert.support.ObjectToOptionalConverter

属性注解工厂

org.springframework.format.number.NumberFormatAnnotationFormatterFactory
根据类路径判断加载javax.money.MonetaryAmount
org.springframework.format.number.money.CurrencyUnitFormatter
org.springframework.format.number.money.MonetaryAmountFormatter
org.springframework.format.number.money.Jsr354NumberFormatAnnotationFormatterFactory

日期转换器

org.springframework.format.datetime.DateFormatterRegistrar.DateToLongConverter
org.springframework.format.datetime.DateFormatterRegistrar.DateToCalendarConverter
org.springframework.format.datetime.DateFormatterRegistrar.CalendarToDateConverter
org.springframework.format.datetime.DateFormatterRegistrar.CalendarToLongConverter
org.springframework.format.datetime.DateFormatterRegistrar.LongToDateConverter
org.springframework.format.datetime.DateFormatterRegistrar.LongToCalendarConverter

org.springframework.format.datetime.standard.DateTimeConverters.LocalDateTimeToLocalDateConverter
org.springframework.format.datetime.standard.DateTimeConverters.LocalDateTimeToLocalTimeConverter
org.springframework.format.datetime.standard.DateTimeConverters.ZonedDateTimeToLocalDateConverter
org.springframework.format.datetime.standard.DateTimeConverters.ZonedDateTimeToLocalTimeConverter
org.springframework.format.datetime.standard.DateTimeConverters.ZonedDateTimeToLocalDateTimeConverter
org.springframework.format.datetime.standard.DateTimeConverters.ZonedDateTimeToOffsetDateTimeConverter
org.springframework.format.datetime.standard.DateTimeConverters.ZonedDateTimeToInstantConverter
org.springframework.format.datetime.standard.DateTimeConverters.OffsetDateTimeToLocalDateConverter
org.springframework.format.datetime.standard.DateTimeConverters.OffsetDateTimeToLocalTimeConverter
org.springframework.format.datetime.standard.DateTimeConverters.OffsetDateTimeToLocalDateTimeConverter
org.springframework.format.datetime.standard.DateTimeConverters.OffsetDateTimeToZonedDateTimeConverter
org.springframework.format.datetime.standard.DateTimeConverters.OffsetDateTimeToInstantConverter
org.springframework.format.datetime.standard.DateTimeConverters.CalendarToZonedDateTimeConverter
org.springframework.format.datetime.standard.DateTimeConverters.CalendarToOffsetDateTimeConverter
org.springframework.format.datetime.standard.DateTimeConverters.CalendarToLocalDateConverter
org.springframework.format.datetime.standard.DateTimeConverters.CalendarToLocalTimeConverter
org.springframework.format.datetime.standard.DateTimeConverters.CalendarToLocalDateTimeConverter
org.springframework.format.datetime.standard.DateTimeConverters.CalendarToInstantConverter
org.springframework.format.datetime.standard.DateTimeConverters.LongToInstantConverter
org.springframework.format.datetime.standard.DateTimeConverters.InstantToLongConverter

org.springframework.format.datetime.standard.InstantFormatter
org.springframework.format.datetime.standard.PeriodFormatter
org.springframework.format.datetime.standard.DurationFormatter
org.springframework.format.datetime.standard.YearFormatter
org.springframework.format.datetime.standard.MonthFormatter
org.springframework.format.datetime.standard.YearMonthFormatter
org.springframework.format.datetime.standard.MonthDayFormatter

org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory

日期解析和打印转换器,成对出现

org.springframework.format.datetime.standard.TemporalAccessorPrinter
org.springframework.format.datetime.standardTemporalAccessorParser

根据类路径判断加载org.joda.time.YearMonth

org.springframework.format.datetime.DateFormatterRegistrar.DateToLongConverter
org.springframework.format.datetime.DateFormatterRegistrar.DateToCalendarConverter
org.springframework.format.datetime.DateFormatterRegistrar.CalendarToDateConverter
org.springframework.format.datetime.DateFormatterRegistrar.CalendarToLongConverter
org.springframework.format.datetime.DateFormatterRegistrar.LongToDateConverter
org.springframework.format.datetime.DateFormatterRegistrar.LongToCalendarConverter

org.springframework.format.datetime.joda.JodaTimeConverters.DateTimeToLocalDateConverter
org.springframework.format.datetime.joda.JodaTimeConverters.DateTimeToLocalTimeConverter
org.springframework.format.datetime.joda.JodaTimeConverters.DateTimeToLocalDateTimeConverter
org.springframework.format.datetime.joda.JodaTimeConverters.DateTimeToDateMidnightConverter
org.springframework.format.datetime.joda.JodaTimeConverters.DateTimeToMutableDateTimeConverter
org.springframework.format.datetime.joda.JodaTimeConverters.DateTimeToInstantConverter
org.springframework.format.datetime.joda.JodaTimeConverters.DateTimeToDateConverter
org.springframework.format.datetime.joda.JodaTimeConverters.DateTimeToCalendarConverter
org.springframework.format.datetime.joda.JodaTimeConverters.DateTimeToLongConverter
org.springframework.format.datetime.joda.JodaTimeConverters.DateToReadableInstantConverter
org.springframework.format.datetime.joda.JodaTimeConverters.CalendarToReadableInstantConverter
org.springframework.format.datetime.joda.JodaTimeConverters.LongToReadableInstantConverter
org.springframework.format.datetime.joda.JodaTimeConverters.LocalDateTimeToLocalDateConverter
org.springframework.format.datetime.joda.JodaTimeConverters.LocalDateTimeToLocalTimeConverter

org.springframework.format.datetime.joda.PeriodFormatter
org.springframework.format.datetime.joda.DurationFormatter
org.springframework.format.datetime.joda.YearMonthFormatter
org.springframework.format.datetime.joda.MonthDayFormatter

org.springframework.format.datetime.joda.JodaDateTimeFormatAnnotationFormatterFactory
根据类路径加载org.joda.time.YearMonth成对出现
org.springframework.format.datetime.joda.ReadablePartialPrinter
org.springframework.format.datetime.joda.LocalDateParser

org.springframework.format.datetime.joda.ReadablePartialPrinter
org.springframework.format.datetime.joda.LocalTimeParser

org.springframework.format.datetime.joda.ReadablePartialPrinter
org.springframework.format.datetime.joda.LocalDateTimeParser

org.springframework.format.datetime.joda.ReadableInstantPrinter
org.springframework.format.datetime.joda.DateTimeParser
如果类路径中没有org.joda.time.YearMonth
org.springframework.format.datetime.DateFormatterRegistrar.DateToLongConverter
org.springframework.format.datetime.DateFormatterRegistrar.DateToCalendarConverter
org.springframework.format.datetime.DateFormatterRegistrar.CalendarToDateConverter
org.springframework.format.datetime.DateFormatterRegistrar.CalendarToLongConverter
org.springframework.format.datetime.DateFormatterRegistrar.LongToDateConverter
org.springframework.format.datetime.DateFormatterRegistrar.LongToCalendarConverter

org.springframework.format.datetime.DateTimeFormatAnnotationFormatterFactory
formatter
org.springframework.boot.convert.CharArrayFormatter
org.springframework.boot.convert.InetAddressFormatter
org.springframework.boot.convert.IsoOffsetFormatter

支持分隔字符串的转换器

org.springframework.boot.convert.ArrayToDelimitedStringConverter	 
org.springframework.boot.convert.CollectionToDelimitedStringConverter
org.springframework.boot.convert.DelimitedStringToArrayConverter
org.springframework.boot.convert.DelimitedStringToCollectionConverter

springboot其他的转换器

org.springframework.boot.convert.StringToDurationConverter
org.springframework.boot.convert.DurationToStringConverter
org.springframework.boot.convert.NumberToDurationConverter
org.springframework.boot.convert.DurationToNumberConverter
org.springframework.boot.convert.StringToPeriodConverter
org.springframework.boot.convert.PeriodToStringConverter
org.springframework.boot.convert.NumberToPeriodConverter
org.springframework.boot.convert.StringToDataSizeConverter
org.springframework.boot.convert.NumberToDataSizeConverter
org.springframework.boot.convert.StringToFileConverter
org.springframework.boot.convert.InputStreamSourceToByteArrayConverter

org.springframework.boot.convert.LenientStringToEnumConverterFactory
org.springframework.boot.convert.LenientBooleanToEnumConverterFactory

这些类或者放入或者经过包装放入到GenericConversionServiceconverters
然后ApplicationConversionService经过AbstractEnvironmentpropertyResolver放入了AbstractPropertyResolverconversionService属性中。

propertyResolver 类型是ConfigurationPropertySourcesPropertyResolver,父类是AbstractPropertyResolver.
conversionService类型是ConfigurableConversionService

protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
	MutablePropertySources sources = environment.getPropertySources();
	if (!CollectionUtils.isEmpty(this.defaultProperties)) {
		DefaultPropertiesPropertySource.addOrMerge(this.defaultProperties, sources);
	}
	if (this.addCommandLineProperties && args.length > 0) {
		String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME;
		if (sources.contains(name)) {
			PropertySource<?> source = sources.get(name);
			CompositePropertySource composite = new CompositePropertySource(name);
			composite.addPropertySource(
					new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args));
			composite.addPropertySource(source);
			sources.replace(name, composite);
		}
		else {
			sources.addFirst(new SimpleCommandLinePropertySource(args));
		}
	}
}

如果defaultProperties默认属性有值,则合并到sources
如果命令行参数有,则合并到sources中。

protected void configureProfiles(ConfigurableEnvironment environment, String[] args) {}

注释:

配置此应用程序环境的活动配置文件(或默认情况下为活动配置文件)。在配置文件处理过程中,可以通过spring.profiles.active属性激活其他配置文件

public static void attach(Environment environment) {
	Assert.isInstanceOf(ConfigurableEnvironment.class, environment);
	MutablePropertySources sources = ((ConfigurableEnvironment) environment).getPropertySources();
	PropertySource<?> attached = getAttached(sources);
	if (attached == null || !isUsingSources(attached, sources)) {
		attached = new ConfigurationPropertySourcesPropertySource(ATTACHED_PROPERTY_SOURCE_NAME,
				new SpringConfigurationPropertySources(sources));
	}
	sources.remove(ATTACHED_PROPERTY_SOURCE_NAME);
	sources.addFirst(attached);
}

查询名称为configurationProperties属性集合,如果没有就把sources包装成ConfigurationPropertySourcesPropertySource放入sources,放在首位。

;