我有 Spring 转换器,它使用名为 EnumTranslator
的 Spring Data REST 组件
@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);
}
}
注册此类转换器的推荐方法是子类化RepositoryRestConfigurerAdapter
,如下所示:
@Configuration
public class RepositoryRestConfig extends RepositoryRestConfigurerAdapter {
private final TranslationStringToSpecificationStatusEnumConverter converter;
@Autowired
public RepositoryRestConfig(TranslationStringToSpecificationStatusEnumConverter converter) {
this.converter = converter;
}
@Override
public void configureConversionService(ConfigurableConversionService conversionService) {
conversionService.addConverter(converter);
super.configureConversionService(conversionService);
}
}
当我运行 Spring Boot 应用程序时,它在以下情况下失败:
***************************
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 依赖项?
最佳答案
要使其正常工作:
@Override
public void configureConversionService(ConfigurableConversionService conversionService) {
conversionService.addConverter(String.class, Status.class, new StringToTranslatedEnumConverter<>(Status.class));
super.configureConversionService(conversionService);
}
首先,我创建了实用程序类来帮助我在非托管对象中使用 Spring beans:
@Component
public final class SpringUtils {
@Autowired private ApplicationContext ctx;
private static SpringUtils instance;
@PostConstruct
private void registerInstance() {
instance = this;
}
public static <T> T getBean(Class<T> clazz) {
return instance.ctx.getBean(clazz);
}
}
然后我创建了转换器:
public class StringToTranslatedEnumConverter<T extends Enum<T> & TranslatedEnum> implements Converter<String, T> {
private final ConcurrentMapCache cache;
private EnumTranslator enumTranslator;
private Class<T> type;
public StringToTranslatedEnumConverter(Class<T> type) {
this.type = type;
cache = new ConcurrentMapCache(type.getName());
}
@Override
public T convert(String from) {
if (enumTranslator == null) {
enumTranslator = SpringUtils.getBean(EnumTranslator.class);
}
Cache.ValueWrapper wrapper = cache.get(from);
if (wrapper != null) {
//noinspection unchecked
return (T) wrapper.get();
}
T translatedEnum = enumTranslator.fromText(type, from);
cache.put(from, translatedEnum);
return translatedEnum;
}
}
已更新
TranslatedEnum
- 它是接口(interface)标记,用于标记只需要翻译的枚举。
public interface TranslatedEnum {
}
public enum Status implements TranslatedEnum {
CREATED, DELETED
}
关于spring - 如何在 Spring Data Rest 应用程序中注册 Converter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48931256/