如何在Spring Data Rest应用程序中注册转换器
我有一个SpringConverter,它使用SpringDataREST的组件如何在Spring Data Rest应用程序中注册转换器,spring,spring-data-rest,Spring,Spring Data Rest,我有一个SpringConverter,它使用SpringDataREST的组件EnumTranslator @Component public class TranslationStringToSpecificationStatusEnumConverter implements Converter<String, Specification.Status> { private final EnumTranslator enumTranslator; @Auto
EnumTranslator
@Component
public class TranslationStringToSpecificationStatusEnumConverter implements Converter<String, Specification.Status> {
private final EnumTranslator enumTranslator;
@Autowired
public TranslationStringToSpecificationStatusEnumConverter(EnumTranslator enumTranslator) {
this.enumTranslator = enumTranslator;
}
@Override
public Specification.Status convert(String source) {
return enumTranslator.fromText(Specification.Status.class, source);
}
}
当我运行Spring引导应用程序时,它在以下情况下失败:
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| translationStringToSpecificationStatusEnumConverter defined in file ...
↑ ↓
| org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration (field java.util.List org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration.configurers)
↑ ↓
| repositoryRestConfig defined in file ...
└─────┘
因此存在循环bean依赖
如何注册上面的转换器,以便不引入循环bean依赖关系?要使其工作:
@覆盖
公共void配置转换服务(ConfigurableConversionService转换服务){
conversionService.addConverter(String.class、Status.class、new StringToTranslatedEnumConverter(Status.class));
super.configureConversionService(conversionService);
}
首先,我创建了帮助我在非托管对象中使用SpringBean的实用程序类:
@组件
公共期末班{
@自动连线专用应用程序上下文ctx;
私有静态SpringUtils实例;
@施工后
私有无效注册表状态(){
实例=此;
}
公共静态T getBean(类clazz){
返回instance.ctx.getBean(clazz);
}
}
然后我创建了转换器:
公共类StringToTranslatedEnumConverter实现转换器{
私有最终ConcurrentMapCache缓存;
私人翻译;
私人阶级类型;
public StringToTranslatedEnumConverter(类类型){
this.type=type;
cache=新的ConcurrentMapCache(type.getName());
}
@凌驾
公共T转换(字符串从){
如果(enumTranslator==null){
enumTranslator=SpringUtils.getBean(enumTranslator.class);
}
Cache.ValueWrapper=Cache.get(从);
if(包装器!=null){
//未检查
return(T)wrapper.get();
}
T translatedEnum=enumTranslator.fromText(类型,from);
cache.put(from,translatedum);
返回翻译场;
}
}
已更新
translatedum
-它是接口标记,用于标记只需要翻译的枚举
public interface TranslatedEnum {
}
public enum Status implements TranslatedEnum {
CREATED, DELETED
}
这个问题的解决方案是特定于Spring核心的。为了打破循环bean依赖循环,我们必须延迟在
RepositoryRestConfig
中设置转换器。它可以通过setter注入实现:
@Component
public class RepositoryRestConfig extends RepositoryRestConfigurerAdapter {
private TranslationStringToSpecificationStatusEnumConverter converter;
@Override
public void configureConversionService(ConfigurableConversionService conversionService) {
conversionService.addConverter(converter);
super.configureConversionService(conversionService);
}
@Autowired
public void setConverter(TranslationStringToSpecificationStatusEnumConverter converter) {
this.converter = converter;
}
}
您可以在Greg Turnquist的这个提交中找到如何解决它:显示EnumTranslator类什么是
TranslatedEnum
?为什么需要SpringUtils
类?为什么不能在StringToTranslatedEnumConverter
中自动连接EnumTranslator
?@PatrikMihalčin我更新了答案。。。我们可以插入EnumTranslator
,但它不会工作,因为我们使用其构造函数实例化转换器:conversionService.addConverter(String.class,Status.class,new StringToTranslateNumConverter(Status.class))代码>谢谢更新。。你的解决方案有效。。但它有点黑客:)(尤其是SpringUtils
)的使用。。与此同时,我收到了格雷格·特恩奎斯特的答复:是的。。我刚贴出来,我没想到!将把它投入使用。)
@Component
public class RepositoryRestConfig extends RepositoryRestConfigurerAdapter {
private TranslationStringToSpecificationStatusEnumConverter converter;
@Override
public void configureConversionService(ConfigurableConversionService conversionService) {
conversionService.addConverter(converter);
super.configureConversionService(conversionService);
}
@Autowired
public void setConverter(TranslationStringToSpecificationStatusEnumConverter converter) {
this.converter = converter;
}
}