我有一个自定义StringToBooleanConverter
应该替换 Spring 附带的默认转换器。因此,源和目标类型完全相同。但是不是替换现有的 Spring 转换器,而是添加了我的转换器。如果我调试应用程序,我可以在Map
转换服务#转换器的同一映射条目中看到两个转换器。
转换服务配置如下:
@Bean
open fun conversionService(converters: Set<Converter<*, *>>) =
ConversionServiceFactoryBean().apply { setConverters(converters) }
@Bean
open fun stringToBooleanConverter() = MyStringToBooleanConverter()
// some more converters not relevant here ...
问题是有时会使用错误的转换器。
如何删除/替换/隐藏/停用 Spring 提供的转换器?
诀窍是定义一个自定义ConversionServiceFactoryBean
,覆盖方法createConversionService
,并删除 Spring 本身注册的StringToBooleanConverter
:
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
无关的错误有关。
更新
如果你运行的是 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)
您可以使用以下方法删除豆子:
((AnnotationConfigEmbeddedWebApplicationContext)
ctx).removeBeanDefinition("yourBeanName")
原始建议
这与这里的一个相关问题有关:https://stackoverflow.com/a/12447211/857994。 实际上,您只想删除现有的 Bean。
您可以获取对 Bean 工厂的引用,并手动从中删除旧 Bean。 我认为最直接的方法可能是评论中建议的方法:"Just implement BeanFactoryAware and then cast BeanFactory with DefaultListableBeanFactory"
.
我不相信有办法首先阻止豆子的供应,因为它来自春天本身。 您可以注释自己的豆子以避免自动布线,我不知道如何在弹簧提供的豆子上实现这一点。