Как избежать дублирования конвертера в Spring ConversionService? - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть пользовательский 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?

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Хитрость заключается в том, чтобы определить пользовательский 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.

0 голосов
/ 18 сентября 2018

Обновление

Если вы работаете с Spring Boot, вы можете запустить свое приложение следующим образом и получить бин следующим образом.

ApplicationContext ctx = SpringApplication.run(Main.class, args);
DispatcherServlet servlet = (DispatcherServlet)ctx.getBean("dispatcherServlet");

Вы можете перечислитьвсе bean-компоненты с:

ctx.getBeanDefinitionNames()

Обратите внимание, что большинство из них просто названы как имя класса с первой буквой в нижнем регистре (для вас будет принят «stringToBooleanConverter»).У некоторых есть имя пакета впереди и затем это.Вы можете легко проверить это в отладчике:).

Вы можете найти bean-компонент определенного типа класса, как этот (обратите внимание, что это определение возвращает ноль в моем случае; так что эта зависимость, кажется, нев моем заявлении):

ctx.getBean(StringToBooleanConverter.class)

Вы можете удалить компонент с помощью:

((AnnotationConfigEmbeddedWebApplicationContext)
     ctx).removeBeanDefinition("yourBeanName")

Исходное предложение

Это связано в связанном вопросездесь: https://stackoverflow.com/a/12447211/857994. реалистично, вы просто хотите удалить существующий компонент.

Вы можете получить ссылку на фабрику компонентов и удалить старый компонент из нее вручную.Я думаю, что наиболее прямым методом, вероятно, будет тот, который предлагается в комментарии: "Just implement BeanFactoryAware and then cast BeanFactory with DefaultListableBeanFactory".

Я не верю, что существует способ остановить предоставление компонента в первую очередь, так как он приходитот самой весны.Вы можете аннотировать свои собственные bean-компоненты, чтобы избежать автоматического подключения, хотя я не знаю, как вы могли бы добиться этого на бобе, предоставляемом пружиной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...