使用Spring mvc-3。我正在编写一个自定义转换器,需要访问注册到ConversionService的其他转换器。
我怎样才能做到这一点?我尝试将自定义转换器编写为:
class CustomConverter<X, Y>{
@Autowired ConversionService service;
//+getter & setters of service
public Y convert(X input){
// I need access to service to lookup simple conversions such as
// String array to Long array etc..
}
}
我通过applicationContext.xml
注册了自定义转换器 <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name = "converters">
<list>
<bean class="CustomConverter"/>
</list>
</property>
</bean>
但是,spring拒绝将服务注入我的CustomConverter(它总是为null)。我怎么能做到这一点?
谢谢!
答案 0 :(得分:8)
我遇到过同样的问题。 Spring JIRA中有一个issue SPR-6415来解决这个问题。我根据本期的讨论给出了我的解决方案。这与@nmervaillie的答案相同,但您不必实现自己的ConversionServiceFactoryBean
。
/**
* Base class of @{code Converter} that need to use {@code ConversionService}.
* Instances of implementing classes must be spring-managed to inject ConversionService.
*
* @author Michal Kreuzman
*/
public abstract class CoversionServiceAwareConverter<S, T> implements Converter<S, T> {
@Inject
private ConversionService conversionService;
protected ConversionService conversionService() {
return conversionService;
}
/**
* Add this converter to {@code ConverterRegistry}.
*/
@SuppressWarnings("unused")
@PostConstruct
private void register() {
if (conversionService instanceof ConverterRegistry) {
((ConverterRegistry) conversionService).addConverter(this);
} else {
throw new IllegalStateException("Can't register Converter to ConverterRegistry");
}
}
}
@Component
public class SampleConverter extends CoversionServiceAwareConverter<Object, Object> {
@Override
public String convert(Object source) {
ConversionService conversionService = conversionService();
// Use conversionService and convert
}
}
答案 1 :(得分:7)
我最近用过这样的东西来解决这个问题。 使用自定义工厂:
public class MyConversionServiceFactoryBean extends ConversionServiceFactoryBean {
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
ConversionService conversionService = getObject();
ConverterRegistry registry = (ConverterRegistry) conversionService;
// register converters that need a nested conversion service
registry.addConverter(new MyCustomConverter(conversionService));
}
}
声明如下:
<bean id="conversionService"
class="com.company.MyConversionServiceFactoryBean">
<property name="converters">
<list>
... declare standard converters here ...
</list>
</property>
</bean>
答案 2 :(得分:0)
主要问题(我遇到过的)是当你使用ConversionServiceFactoryBean
构建conversion service
时,其中包含使用conversion service
的转换器,因为{{1}会导致错误在ConversionServiceFactoryBean.getObject
之前调用提供conversion service
实例的方法,其中实际创建了转换服务实例。
因此,以避免此行为,您只需要在ConversionServiceFactoryBean.afterPropertiesSet
之前创建conversion service
。我已经在扩展ConversionServiceFactoryBean.getObject
的类的构造函数中创建了它。
例如:
ConversionServiceFactoryBean
您也可以使用使用 try {
Field serviceField = ConversionServiceFactoryBean.class.getDeclaredField("conversionService");
conversionServiceField.setAccessible(true);
conversionServiceField.set(this, createConversionService());
} catch (NoSuchFieldException | IllegalAccessException fieldAccessError) {
fieldAccessError.printStackTrace();
//or do some log output here, it's up to you
}
的转换器。
希望它有所帮助。