У меня есть собственный StringToBooleanConverter, который должен заменить конвертер по умолчанию, поставляемый с Spring. Таким образом, исходный и целевой типы абсолютно одинаковы. Но вместо замены существующего конвертера Spring добавлен мой конвертер. Если я отлаживаю приложение, я вижу оба преобразователя в одной записи карты преобразователей Map ConversionService #.
ConversionService настроен следующим образом:
@Bean
open fun conversionService(converters: Set<Converter<*, *>>) =
ConversionServiceFactoryBean().apply { setConverters(converters) }
@Bean
open fun stringToBooleanConverter() = MyStringToBooleanConverter()
// some more converters not relevant here ...
Проблема в том, что иногда используются неправильные преобразователи.
Как я могу удалить / заменить / скрыть / деактивировать конвертер, поставляемый Spring?




Обновлять
Если вы используете Spring Boot, вы можете запустить свое приложение следующим образом и получить bean-компонент следующим образом.
ApplicationContext ctx = SpringApplication.run(Main.class, args);
DispatcherServlet servlet = (DispatcherServlet)ctx.getBean("dispatcherServlet");
Вы можете перечислить все бобы с помощью:
ctx.getBeanDefinitionNames()
Обратите внимание, что большинство из них просто названо как имя класса с первой буквы в нижнем регистре (для вас это будет "stringToBooleanConverter"). У некоторых впереди имя пакета, а затем это. Вы можете легко проверить это в отладчике :).
Вы можете найти bean-компонент определенного типа класса, подобный этому (обратите внимание, что это определение возвращает null в моем случае; поэтому эта зависимость, похоже, отсутствует в моем приложении):
ctx.getBean(StringToBooleanConverter.class)
Вы можете удалить bean-компонент с помощью:
((AnnotationConfigEmbeddedWebApplicationContext)
ctx).removeBeanDefinition("yourBeanName")
Оригинальное предложение
Это связано со связанным вопросом здесь: https://stackoverflow.com/a/12447211/857994. На самом деле вы просто хотите удалить существующий компонент.
Вы можете получить ссылку на фабрику bean-компонентов и вручную удалить с нее старый bean-компонент. Я думаю, что наиболее прямым методом, вероятно, будет тот, который предлагается в комментарии: "Just implement BeanFactoryAware and then cast BeanFactory with DefaultListableBeanFactory".
Я не верю, что есть способ вообще прекратить подачу бобов, поскольку они происходят из самой весны. Вы можете аннотировать свои собственные bean-компоненты, чтобы избежать автосоединения, хотя я не знаю, как вы могли бы добиться этого на bean-компонентах, предоставляемых Spring.
Собственные конвертеры Spring не зарегистрированы как beans, как вы можете видеть в DefaultConversionService. Таким образом, невозможно удалить преобразователь, удалив bean-компонент.
Хитрость заключается в том, чтобы определить собственный ConversionServiceFactoryBean, переопределить метод createConversionService и удалить StringToBooleanConverter, зарегистрированный самим Spring:
class ConversionServiceFactoryWithoutStringToBooleanConverter : ConversionServiceFactoryBean() {
override fun createConversionService(): GenericConversionService {
val conversionService = super.createConversionService()
conversionService.removeConvertible(String::class.java, java.lang.Boolean::class.java)
return conversionService
}
}
Однако в этом случае нет необходимости удалять преобразователь Spring, потому что, если существует более одного преобразователя для определенного источника и целевого типа, Spring пробует их по порядку, и преобразователи, зарегистрированные пользователем, идут первыми. Поведение, которое подтолкнуло меня к этому исследованию, на самом деле было связано с другой ошибкой, не связанной с ConversionService.
Большое спасибо за ваши усилия. Но собственный
StringToBooleanConverterSpring не указан в контексте (сctx..getBeanDefinitionNames()), я могу видеть только свой собственный конвертер. Это невозможно даже для компонента по типу сcontext.getBean(StringToBooleanConverter::class), потому что StringToBooleanConverter не является общедоступным. Это похоже на очень неэлегантный уголок Spring Framework.