一、FormattingConversionServiceFactoryBean
FormattingConversionServiceFactoryBean实现了FactoryBean接口,可以通过getObject获取ConversionService。FormattingConversionServiceFactoryBean提供了快速访问ConversionService工厂,工厂配置了转换器和格式化程序(用于常见类型,如数字和日期时间)。
二、实例化FormattingConversionServiceFactoryBean
AbstractAutowireCapableBeanFactory.initializeBean执行bean的init方法,实现InitializingBean接口的InitializingBean方法,及执行实现BeanPostProcessor接口的postProcessBeforeInitialization和postProcessAfterInitialization。
FormattingConversionServiceFactoryBean.afterPropertiesSet()
public void afterPropertiesSet() {
this.conversionService = new DefaultFormattingConversionService(this.embeddedValueResolver, this.registerDefaultFormatters);
ConversionServiceFactory.registerConverters(this.converters, this.conversionService);
registerFormatters(this.conversionService);
}
1、创建DefaultFormattingConversionService
2、调用ConversionServiceFactory.registerConverters注册给定的converters
3、registerFormatters注册Formatter
DefaultFormattingConversionService
public DefaultFormattingConversionService(
@Nullable StringValueResolver embeddedValueResolver, boolean registerDefaultFormatters) {
if (embeddedValueResolver != null) {
setEmbeddedValueResolver(embeddedValueResolver);
}
DefaultConversionService.addDefaultConverters(this);
if (registerDefaultFormatters) {
addDefaultFormatters(this);
}
}
1、设置ValueResolver
2、添加默认Converter
3、添加默认Formatter
DefaultConversionService.addDefaultConverters(ConverterRegistry converterRegistry)
public static void addDefaultConverters(ConverterRegistry converterRegistry) {
addScalarConverters(converterRegistry);
addCollectionConverters(converterRegistry);
converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry));
converterRegistry.addConverter(new StringToTimeZoneConverter());
converterRegistry.addConverter(new ZoneIdToTimeZoneConverter());
converterRegistry.addConverter(new ZonedDateTimeToCalendarConverter());
converterRegistry.addConverter(new ObjectToObjectConverter());
converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry));
converterRegistry.addConverter(new FallbackObjectToStringConverter());
converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));
}
1、addScalarConverters添加ConverterFactory及Converter,ConverterFactory<S, R>将对象从S转换为R的子类型。
2、addCollectionConverters添加collection converters
3、添加默认Converter
addScalarConverters(ConverterRegistry converterRegistry)
private static void addScalarConverters(ConverterRegistry converterRegistry) {
converterRegistry.addConverterFactory(new NumberToNumberConverterFactory());
converterRegistry.addConverterFactory(new StringToNumberConverterFactory());
converterRegistry.addConverter(Number.class, String.class, new ObjectToStringConverter());
converterRegistry.addConverter(new StringToCharacterConverter());
converterRegistry.addConverter(Character.class, String.class, new ObjectToStringConverter());
converterRegistry.addConverter(new NumberToCharacterConverter());
converterRegistry.addConverterFactory(new CharacterToNumberFactory());
converterRegistry.addConverter(new StringToBooleanConverter());
converterRegistry.addConverter(Boolean.class, String.class, new ObjectToStringConverter());
converterRegistry.addConverterFactory(new StringToEnumConverterFactory());
converterRegistry.addConverter(new EnumToStringConverter((ConversionService) converterRegistry));
converterRegistry.addConverterFactory(new IntegerToEnumConverterFactory());
converterRegistry.addConverter(new EnumToIntegerConverter((ConversionService) converterRegistry));
converterRegistry.addConverter(new StringToLocaleConverter());
converterRegistry.addConverter(Locale.class, String.class, new ObjectToStringConverter());
converterRegistry.addConverter(new StringToCharsetConverter());
converterRegistry.addConverter(Charset.class, String.class, new ObjectToStringConverter());
converterRegistry.addConverter(new StringToCurrencyConverter());
converterRegistry.addConverter(Currency.class, String.class, new ObjectToStringConverter());
converterRegistry.addConverter(new StringToPropertiesConverter());
converterRegistry.addConverter(new PropertiesToStringConverter());
converterRegistry.addConverter(new StringToUUIDConverter());
converterRegistry.addConverter(UUID.class, String.class, new ObjectToStringConverter());
}
比如StringToNumberConverterFactory将String转换成Number的子类型。EnumToStringConverter将Enum转换成String.
addCollectionConverters(ConverterRegistry converterRegistry)
public static void addCollectionConverters(ConverterRegistry converterRegistry) {
ConversionService conversionService = (ConversionService) converterRegistry;
converterRegistry.addConverter(new ArrayToCollectionConverter(conversionService));
converterRegistry.addConverter(new CollectionToArrayConverter(conversionService));
converterRegistry.addConverter(new ArrayToArrayConverter(conversionService));
converterRegistry.addConverter(new CollectionToCollectionConverter(conversionService));
converterRegistry.addConverter(new MapToMapConverter(conversionService));
converterRegistry.addConverter(new ArrayToStringConverter(conversionService));
converterRegistry.addConverter(new StringToArrayConverter(conversionService));
converterRegistry.addConverter(new ArrayToObjectConverter(conversionService));
converterRegistry.addConverter(new ObjectToArrayConverter(conversionService));
converterRegistry.addConverter(new CollectionToStringConverter(conversionService));
converterRegistry.addConverter(new StringToCollectionConverter(conversionService));
converterRegistry.addConverter(new CollectionToObjectConverter(conversionService));
converterRegistry.addConverter(new ObjectToCollectionConverter(conversionService));
converterRegistry.addConverter(new StreamConverter(conversionService));
}
StringToCollectionConverter将String分割后转换成Collection。
DefaultFormattingConversionService.addDefaultFormatters(FormatterRegistry formatterRegistry)
public static void addDefaultFormatters(FormatterRegistry formatterRegistry) {
// Default handling of number values
formatterRegistry.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
// Default handling of monetary values
if (jsr354Present) {
formatterRegistry.addFormatter(new CurrencyUnitFormatter());
formatterRegistry.addFormatter(new MonetaryAmountFormatter());
formatterRegistry.addFormatterForFieldAnnotation(new Jsr354NumberFormatAnnotationFormatterFactory());
}
// Default handling of date-time values
// just handling JSR-310 specific date and time types
new DateTimeFormatterRegistrar().registerFormatters(formatterRegistry);
if (jodaTimePresent) {
// handles Joda-specific types as well as Date, Calendar, Long
new org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar().registerFormatters(formatterRegistry);
}
else {
// regular DateFormat-based Date, Calendar, Long converters
new DateFormatterRegistrar().registerFormatters(formatterRegistry);
}
}
NumberFormatAnnotationFormatterFactory用于处理@NumberFormat标注的字段。@NumberFormat可参考https://blog.csdn.net/weixin_38192427/article/details/122270716
jsr354Present表示是否要处理MonetaryAmount。MonetaryAmount参考https://www.cnblogs.com/vivotech/p/15686492.html。
CurrencyUnitFormatter用于货币类型与String之间相互转换。
MonetaryAmountFormatter用于MonetaryAmount和String之间格式化。
Jsr354NumberFormatAnnotationFormatterFactory处理@NumberFormat标注的字段。
DateTimeFormatterRegistrar().registerFormatters注册date和time类型的Formatter。
DateTimeFormatterRegistrar
public DateTimeFormatterRegistrar() {
for (Type type : Type.values()) {
this.factories.put(type, new DateTimeFormatterFactory());
}
}
private enum Type {DATE, TIME, DATE_TIME}
DateTimeFormatterRegistrar.registerFormatters(FormatterRegistry registry)
public void registerFormatters(FormatterRegistry registry) {
DateTimeConverters.registerConverters(registry);
DateTimeFormatter df = getFormatter(Type.DATE);
DateTimeFormatter tf = getFormatter(Type.TIME);
DateTimeFormatter dtf = getFormatter(Type.DATE_TIME);
// Efficient ISO_LOCAL_* variants for printing since they are twice as fast...
registry.addFormatterForFieldType(LocalDate.class,
new TemporalAccessorPrinter(
df == DateTimeFormatter.ISO_DATE ? DateTimeFormatter.ISO_LOCAL_DATE : df),
new TemporalAccessorParser(LocalDate.class, df));
registry.addFormatterForFieldType(LocalTime.class,
new TemporalAccessorPrinter(
tf == DateTimeFormatter.ISO_TIME ? DateTimeFormatter.ISO_LOCAL_TIME : tf),
new TemporalAccessorParser(LocalTime.class, tf));
registry.addFormatterForFieldType(LocalDateTime.class,
new TemporalAccessorPrinter(
dtf == DateTimeFormatter.ISO_DATE_TIME ? DateTimeFormatter.ISO_LOCAL_DATE_TIME : dtf),
new TemporalAccessorParser(LocalDateTime.class, dtf));
registry.addFormatterForFieldType(ZonedDateTime.class,
new TemporalAccessorPrinter(dtf),
new TemporalAccessorParser(ZonedDateTime.class, dtf));
registry.addFormatterForFieldType(OffsetDateTime.class,
new TemporalAccessorPrinter(dtf),
new TemporalAccessorParser(OffsetDateTime.class, dtf));
registry.addFormatterForFieldType(OffsetTime.class,
new TemporalAccessorPrinter(tf),
new TemporalAccessorParser(OffsetTime.class, tf));
registry.addFormatterForFieldType(Instant.class, new InstantFormatter());
registry.addFormatterForFieldType(Period.class, new PeriodFormatter());
registry.addFormatterForFieldType(Duration.class, new DurationFormatter());
registry.addFormatterForFieldType(Year.class, new YearFormatter());
registry.addFormatterForFieldType(Month.class, new MonthFormatter());
registry.addFormatterForFieldType(YearMonth.class, new YearMonthFormatter());
registry.addFormatterForFieldType(MonthDay.class, new MonthDayFormatter());
registry.addFormatterForFieldAnnotation(new Jsr310DateTimeFormatAnnotationFormatterFactory());
}
增加date和time类型的Formatter。Jsr310DateTimeFormatAnnotationFormatterFactory处理@DateTimeFormat注解标注的字段。
JodaTimeFormatterRegistrar添加Joda类型的日期和时间。
DateFormatterRegistrar添加jdk 的Date,Calendar等的Formatter。
标签:converterRegistry,SpringMVC,addConverter,FormattingConversionServiceFactoryBean, From: https://www.cnblogs.com/shigongp/p/16852218.html