Как зарегистрировать пользовательские конвертеры в spring загрузке?
Я пишу приложение, используя spring -boot-starter-jdbc (v1.3.0).
Проблема, с которой я встречалась: экземпляр BeanPropertyRowMapper
терпит неудачу, поскольку он не может преобразовать из java.sql.Timestamp
в java.time.LocalDateTime
.
Чтобы скопировать эту проблему, я реализовал
org.springframework.core.convert.converter.Converter
для этих типов.
public class TimeStampToLocalDateTimeConverter implements Converter<Timestamp, LocalDateTime> {
@Override
public LocalDateTime convert(Timestamp s) {
return s.toLocalDateTime();
}
}
Мой вопрос: Как сделать доступным TimeStampToLocalDateTimeConverter
для BeanPropertyRowMapper
.
Более общий вопрос, как я могу зарегистрировать свои конвертеры, чтобы сделать их доступными в системе?
Следующий код приводит нас к NullPointerException
на этапе инициализации:
private Set<Converter> getConverters() {
Set<Converter> converters = new HashSet<Converter>();
converters.add(new TimeStampToLocalDateTimeConverter());
converters.add(new LocalDateTimeToTimestampConverter());
return converters;
}
@Bean(name="conversionService")
public ConversionService getConversionService() {
ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
bean.setConverters(getConverters());
bean.afterPropertiesSet();
return bean.getObject();
}
Спасибо.
Ответы
Ответ 1
Я предлагаю использовать @Autowired и соответствующий механизм впрыска зависимостей spring для использования одного экземпляра ConversionService во всем приложении. ConversionService будет создан в конфигурации.
Все конвертеры, доступные для широкого применения, получают аннотацию (например, @AutoRegistered). При запуске приложения @Component FormatterRegistrar (само название типа немного вводит в заблуждение, да, это "... Регистратор", поскольку он регистрирует. И @Component, поскольку он полностью spring управляется и требует инъекции зависимостей), получит @AutoRegistered Список всех аннотированных преобразователей.
Смотрите эту тему для конкретных деталей реализации. Мы используем этот механизм в рамках нашего проекта, и он работает как шарм.
Ответ 2
Попытка добавить
@Converter(autoApply = true)
Его нужно разместить над классом конвертора. Это работает для меня, если для взаимодействия с БД необходим локальный конвертер.
@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate locDate) {
return (locDate == null ? null : Date.valueOf(locDate));
}
@Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}
Это теперь применяется автоматически при взаимодействии с БД.
Ответ 3
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
или любая другая его реализация является одним из основных мест для любой настройки в проекте весенней загрузки. Он предлагает различные методы для вашего конвертера.
Просто создайте новый конвертер, расширяя org.springframework.core.convert.converter.Converter<S, T>
. Затем зарегистрируйте его в Spring с помощью метода переопределения классов org.springframework.web.servlet.config.annotation.WebMvcConfigurer.addFormatters(FormatterRegistry)
Обратите внимание, что существуют и другие типы конвертеров, которые в основном начинаются с ConditionalConverter.