我正在使用Spring Boot 1.5.10并且我的自定义转换器出现问题。
我正在定义目标类型为Optional的多个转换器 像这样:
@Component
public class StringToSomeTypeConverter implements Converter<String, Optional<SomeType>> { ... }
@Component
public class StringToOtherTypeConverter implements Converter<String, Optional<OtherType>> { ... }
我的问题是,显然只有一个转换器注册了Optional类型。所以在运行时只在我的所有控制器中调用一个Converter。无论通用目标类型。 (示例中为SomeType
或OtherType
)
我做了一些挖掘,并在GenericConversionService#getConverter
中选择了转换器。
该方法将TypeDescriptor targetType
作为参数,并从ConverterCacheKey
和sourceType
构建targetType
。
遗憾的是,TypeDescriptor#equals
仅比较getType()
(可选)而非resolvableType
(我们的示例中为SomeType
或OtherType
)。
这解释了为什么只有一个转换器被拾取。
有没有办法让Spring知道ResolvableType
所以我可以使用Optional作为多个转换器的目标类型?
答案 0 :(得分:1)
我无法确定发生了什么,但是多次浏览过Spring MVC源代码我想这个问题会出现在一些代码中,这些代码是迭代注册转换器并检查它们是否可以转换,所以目标类型会如果您运行此代码,则是可选的(不是可选&lt; Class&lt; Integer&gt;&gt;,但是可选):
Optional<Class<String>> ops = Optional.of(String.class);
Optional<Class<Integer>> ops2 = Optional.of(Integer.class);
System.out.println(ops2.getClass().equals(ops.getClass()));
您将在控制台上看到它打印为true,这意味着它们被视为相同的数据类型!因此,如果Spring真正遍历转换器列表,那么总是会调用第一个,因为它可以处理所有可选对象,无论如何,我的建议是:
更新:如果你有兴趣在Spring框架上调试它,你必须在ConversionService接口的方法上放置一个断点,它是管理转换的服务,至少这是它在Spring Core中的工作方式,而你我们应该看到执行流程,并在一个时刻检查哪个转换器是合适的,如果其中一些转换器实现了ConditionalConverter,请自行查看此过程的核心方法之一:https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java#L560