首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何避免Spring ConversionService中的重复转换器?

如何避免Spring ConversionService中的重复转换器?
EN

Stack Overflow用户
提问于 2018-09-18 14:55:24
回答 2查看 1.2K关注 0票数 3

我有一个定制的StringToBooleanConverter,它应该取代随Spring而来的默认转换器。因此,源类型和目标类型完全相同。但是没有替换现有的Spring转换器,而是添加了我的转换器。如果调试应用程序,可以在Map ConversionService#converters的同一个映射条目中看到两个转换器。

ConversionService的配置如下:

代码语言:javascript
复制
@Bean
open fun conversionService(converters: Set<Converter<*, *>>) =
        ConversionServiceFactoryBean().apply { setConverters(converters) }

@Bean
open fun stringToBooleanConverter() = MyStringToBooleanConverter()

// some more converters not relevant here ...

问题是,有时使用错误的转换器。

如何删除/替换/隐藏/停用Spring交付的转换器?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-09-20 13:50:08

诀窍是定义一个自定义ConversionServiceFactoryBean,重写createConversionService方法,并删除StringToBooleanConverter本身注册的StringToBooleanConverter

代码语言:javascript
复制
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无关的bug有关。

票数 2
EN

Stack Overflow用户

发布于 2018-09-18 15:10:14

更新

如果您正在运行Spring,您可以像这样启动应用程序并获得一个bean,如下所示。

代码语言:javascript
复制
ApplicationContext ctx = SpringApplication.run(Main.class, args);
DispatcherServlet servlet = (DispatcherServlet)ctx.getBean("dispatcherServlet");

您可以通过以下方式列出所有bean:

代码语言:javascript
复制
ctx.getBeanDefinitionNames()

请注意,大多数用户只是将类名命名为带有小写第一个字母的类名(您将假定为"stringToBooleanConverter“)。有些人把包的名字放在前面,然后是那个。您可以很容易地在调试器中检查这一点:)。

您可以找到这样一个特定类类型的bean (请注意,在我的示例中,这个定义返回null;因此这个依赖项似乎不在我的应用程序中):

代码语言:javascript
复制
ctx.getBean(StringToBooleanConverter.class)

您可以使用以下方法删除bean:

代码语言:javascript
复制
((AnnotationConfigEmbeddedWebApplicationContext)
     ctx).removeBeanDefinition("yourBeanName")

原始建议

这与这里的一个相关问题有关:https://stackoverflow.com/a/12447211/857994。实际上,您只想删除现有的bean。

您可以获得对bean工厂的引用,并手动从其中移除旧bean。我认为最直接的方法可能是在评论中建议的方法:"Just implement BeanFactoryAware and then cast BeanFactory with DefaultListableBeanFactory"

我不相信一开始就有办法阻止豆子的供应,因为它来自春天本身。您可以注释您自己的bean,以避免自动装配,但我不知道您如何才能在春季提供的bean上实现这一点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52389381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档